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