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.

CC3220 TCP socket超时设置Bug



在AP模式设置为 TCP server,使用了TCP socket 超时设置,当socket  server与第一个TCP client 建立连接后,进行socket通信,client 不发数据,socket不会超时,当第二个client接入就会超时,或者将第一个 tcp client关闭,再次连接创建为client ID 0x01的socket就会出现超时 ,

void BsdTcpServer1(uint32_t arg0)
{
void *thread = NULL;
int status;
int clientfd;
int server;
struct sockaddr_in localAddr;
struct sockaddr_in clientAddr;
int optval;
int optlen = sizeof(optval);
socklen_t addrlen = sizeof(clientAddr);
struct SlTimeval_t TimeVal;

UART_PRINT("TCP Server1 example started\n");
// UART_PRINT("Creating TCP socket\n\r");
server = socket(AF_INET, SOCK_STREAM, 0);
if (server == -1) {
UART_PRINT("tcpHandler1: socket failed\n");
goto shutdown;
}


memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(arg0);
//localAddr.sin_port = htons(arg0+1);

status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
if (status == -1) {
UART_PRINT("tcpHandler: bind failed\n");
goto shutdown;
}

status = listen(server, NUMTCPWORKERS);
if (status == -1) {
UART_PRINT("tcpHandler: listen failed\n");
goto shutdown;
}

optval = 1;
status = setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
// status =sl_SetSockOpt(server,SL_SOL_SOCKET,SL_SO_NONBLOCKING,(_u8*)&optval,optlen);
// status = setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
if (status == -1) {
UART_PRINT("tcpHandler: setsockopt failed\n");
goto shutdown;
}

TimeVal.tv_sec = 7; // Seconds
TimeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution

// setting socket option to enable receive timeout
status = sl_SetSockOpt(server, SL_SOL_SOCKET, SL_SO_RCVTIMEO,
(_u8 *)&TimeVal, sizeof(TimeVal));
if(status < 0)
{
UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,
SL_SOCKET_ERROR);
//sl_Close(server);
// return(-1);
}

while ((clientfd =
accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1)
{

UART_PRINT(
"tcpHandler: Creating thread clientfd = %x\n", clientfd);
// TimeVal.tv_sec = 7; // Seconds
// TimeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution
//
// // setting socket option to enable receive timeout
// status = sl_SetSockOpt(server, SL_SOL_SOCKET, SL_SO_RCVTIMEO,
// (_u8 *)&TimeVal, sizeof(TimeVal));
// if(status < 0)
// {
// UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,
// SL_SOCKET_ERROR);
// //sl_Close(server);
// // return(-1);
// }

thread = TaskCreate(tcpServerWorker1, NULL, 3, 2048, (uintptr_t)clientfd,
0, 0);
#if 1
// tcpServerWorker1(clientfd,0);
// sleep(1);
#endif

if (!thread) {
UART_PRINT(
"tcpHandler1: Error - Failed to create new thread.\n");
close(clientfd);
}

/* addrlen is a value-result param, must reset for next accept call */
addrlen = sizeof(clientAddr);
}

UART_PRINT("tcpHandler1: accept failed.\n");

shutdown:
if (server != -1) {
close(server);
}

pthread_exit(0);

}


void tcpServerWorker1(uint32_t arg0, uint32_t arg1)
{
int clientfd = (int)arg0;
int bytesRcvd;
int bytesSent;
char buffer[TCPPACKETSIZE];

UART_PRINT("tcpWorker1: start clientfd = 0x%x\n",
clientfd);

while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0)
{
UART_PRINT("tcpWorker: Receivd clientfd = 0x%x\n",
clientfd);
UART_PRINT("TCP Server1 Receivd %d Byte \n",
bytesRcvd);
sleep(1);
bytesSent = send(clientfd, buffer, bytesRcvd, 0);
if (bytesSent < 0 || bytesSent != bytesRcvd)
{
UART_PRINT("send failed.\n");
break;
}
}
UART_PRINT("tcpWorker1 stop clientfd = 0x%x\n", clientfd);

close(clientfd);
pthread_detach ( pthread_self ( ) );
pthread_exit(0);
}

  • 统一使用socket.h定义的API,不混用sl_socket.h的API,同时在每次监听到 socket client 后进行超时设置,就可以对每一个socket client进行接收超时监控
    while ((clientfd = accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1)
    {
    // setting socket option to enable receive timeout
    TimeVal.tv_sec = 7; // Seconds
    TimeVal.tv_usec = 0; // Microseconds. 10000 microseconds resolution
    status = setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO,(_u8 *)&TimeVal, sizeof(TimeVal));

    if(status < 0)
    {
    UART_PRINT("[line:%d, error:%d] %s\n\r", __LINE__, status,
    SL_SOCKET_ERROR);
    close(clientfd);
    // sl_Close(server);
    }

    UART_PRINT("tcpHandler: Creating thread clientfd = %x\n", clientfd);

    thread = TaskCreate(TcpServerWorker, NULL, 3, 2048, (uintptr_t)clientfd, 0, 0);

    if (!thread)
    {
    UART_PRINT( "tcpHandler: Error - Failed to create new thread.\n");
    close(clientfd);
    sleep(1);
    }

    /* addrlen is a value-result param, must reset for next accept call */
    addrlen = sizeof(clientAddr);
    }