This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM437x NDK TCP server how to support multi-connection

Other Parts Discussed in Thread: SYSBIOS

Hi,

My hardware is AM437x IDK EVM 

SYS/BIOS 6.41.4.54

NDK       2.24.2.31

XDC       3.31.1.33

IDK       sysbios_ind_sdk_2.1.0.1

I successfully boot the NDK based the ethernetip_adapter example and I can use the TCP to receive and send data. But when I update it to support multi-connection the recv() function always return -1.

The followed code could work well but it doesn't support multi-connection.

void MBsocketTaskFunc(UArg arg0, UArg arg1) {

	SOCKET s = INVALID_SOCKET;
	SOCKET s2 = INVALID_SOCKET;
	struct sockaddr_in sin1;
	int res = 0;
	int size = 0;
	char IPaddress[] = "192.168.2.2";

	int rcLen =0;
	char buffer[128];
	int i=0;

	fdOpenSession(TaskSelf());

	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET) {
		CONSOLEUtilsPrintf("fail to create socket (%d) \r\n", fdError());
		Task_exit();
	}

	bzero(&sin1, sizeof(struct sockaddr_in));
	sin1.sin_family = AF_INET;
	sin1.sin_addr.s_addr = inet_addr(IPaddress);
	sin1.sin_port = htons(502);

	/* Bind the socket */
	if (bind(s, (PSA) & sin1, sizeof(sin1)) < 0) {
		CONSOLEUtilsPrintf("failed bind (%d)\n", fdError());
		fdClose(s);
		Task_exit();
	}

	/* Start listening */
	if (listen(s, 5) < 0) {
		CONSOLEUtilsPrintf("failed listen (%d)\n", fdError());
		fdClose(s);
		Task_exit();
	}

	size = sizeof(sin1);
	CONSOLEUtilsPrintf("before s2 value and address: %x  %x\r\n",s2,&s2);
	while (1) {
		s2 = accept(s, (PSA) & sin1, &size);
		CONSOLEUtilsPrintf("s2 value and address: %x  %x\r\n",s2,&s2);

		if (s2 == INVALID_SOCKET) {
			CONSOLEUtilsPrintf("failed accept (%d)\n", fdError());
			continue;
		}
		CONSOLEUtilsPrintf("accept ok \r\n");

		rcLen = recv(s2, buffer, 127, MSG_PEEK);
		CONSOLEUtilsPrintf("received data length  is: (%d)\r\n", rcLen);

		if (rcLen < 0) {
			CONSOLEUtilsPrintf("fail to recv (%d)\r\n", fdError());
			continue;
		}

		CONSOLEUtilsPrintf("recveived data is:\r\n");
		for (i = 0; i < rcLen; i++) {
			CONSOLEUtilsPrintf("%x", buffer[i]);
		}

		//process the data

		if (send(s2, buffer, rcLen, 0)) {
			CONSOLEUtilsPrintf("fail to send (%d)\r\n", fdError());
			continue;
		}
		bzero(buffer, 128);
		fdClose(s2);

	}

	fdCloseSession(TaskSelf());
}

In order to support multi-connection, I create an new task when the socket accepts a connection and the new task could process the connection separately.

void MBsocketTaskFunc(UArg arg0, UArg arg1) {

	SOCKET s = INVALID_SOCKET;
	SOCKET s2 = INVALID_SOCKET;
	struct sockaddr_in sin1;
	int res = 0;
	int size = 0;
	char IPaddress[] = "192.168.2.2";

	Task_Params taskParams;

	fdOpenSession(TaskSelf());

	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET) {
		CONSOLEUtilsPrintf("fail to create socket (%d) \r\n", fdError());
		Task_exit();
	}

	bzero(&sin1, sizeof(struct sockaddr_in));
	sin1.sin_family = AF_INET;
	sin1.sin_addr.s_addr = inet_addr(IPaddress);
	sin1.sin_port = htons(502);

	/* Bind the socket */
	if (bind(s, (PSA) & sin1, sizeof(sin1)) < 0) {
		CONSOLEUtilsPrintf("failed bind (%d)\n", fdError());
		fdClose(s);
		Task_exit();
	}

	/* Start listening */
	if (listen(s, 5) < 0) {
		CONSOLEUtilsPrintf("failed listen (%d)\n", fdError());
		fdClose(s);
		Task_exit();
	}

	size = sizeof(sin1);
	CONSOLEUtilsPrintf("before s2 value and address: %x  %x\r\n",s2,&s2);
	while (1) {
		s2 = accept(s, (PSA) & sin1, &size);
		CONSOLEUtilsPrintf("s2 value and address: %x  %x\r\n",s2,&s2);

		if (s2 == INVALID_SOCKET) {
			CONSOLEUtilsPrintf("failed accept (%d)\n", fdError());
			continue;
		}
		CONSOLEUtilsPrintf("accept ok \r\n");

/* create new task to process */ Task_Params_init(&taskParams); taskParams.stackSize = 0x1000; taskParams.priority = 5; taskParams.arg0 = (UArg)s2; if(Task_create (mainTaskFunc, &taskParams, NULL)==NULL) { CONSOLEUtilsPrintf("fail to create task"); } } fdCloseSession(TaskSelf()); } void mainTaskFunc(UArg arg0, UArg arg1){ SOCKET s = (SOCKET)arg0; int32_t rcLen = 0; uint32_t i =0; uint8_t* buffer = NULL; buffer = malloc(128); if(buffer == NULL){ //do some thing CONSOLEUtilsPrintf("fail to malloc for buffer"); } while(1){
rcLen = recv(s, buffer, 128, 0); /* Here recv() should block but it always immediately return -1 and fdError() is -1,too */ CONSOLEUtilsPrintf("received data length is: (%d)\r\n", rcLen); if (rcLen <= 0) { CONSOLEUtilsPrintf("recv failed (%d)\r\n", fdError()); continue; } CONSOLEUtilsPrintf("recv data is:\r\n"); for (i = 0; i < rcLen; i++) { CONSOLEUtilsPrintf("%c", buffer[i]); } //other things if (send(s, buffer, rcLen, 0)) { CONSOLEUtilsPrintf("send failed (%d)\r\n", fdError()); continue; } } fdClose(s); free(buffer); }

When I create new task to process the connection the recv() function is non-block and return (-1) immediately. The fdError() return -1, too.

Thanks very much.

Best regards,

Qinghai