我用CC3200模块做TCP SERVER时,只有一个TCP客户端反复断开、连接,大概4次以后无法再连接。分析是达到socket连接限制(因为还有其他套接字),但客户端正常断开后 sl_Recv返回0,我在返回0后有关闭套接字,为什么还会出现这种情况呢,请问是什么问题?
while(1)
{
// waiting for an app incoming TCP connection
if ( g_iSockID_App < 0 )
{
// accepts a connection form a TCP client, if there is any
// otherwise returns SL_EAGAIN
g_iSockID_App = sl_Accept(g_iSockID_AppServer, ( struct SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize);
if (g_iSockID_App == SL_EAGAIN)
{
//sl_Close(g_iSockID_App);
}
else if(g_iSockID_App < 0)
{
// error
sl_Close(g_iSockID_App);
}
else
{
// setting socket option to make the socket as non blocking
enableOption.NonblockingEnabled = 1; //0 = disabled;1 = enabled;default = 1
lRetVal = sl_SetSockOpt(g_iSockID_App,SL_SOL_SOCKET,SL_SO_NONBLOCKING, (_u8 *)&enableOption,sizeof(enableOption));
//enable/disable nonblocking mode
if( lRetVal < 0 )
{
sl_Close(g_iSockID_App);
}
}
}
else
{
// waits for 1 packets from the connected TCP client
lRetVal = sl_Recv(g_iSockID_App, g_cAppTcpBuf, TCP_CMD_RD_BUF_SIZE, 0);
if (lRetVal == SL_EAGAIN);
else if(lRetVal <=0)
{
// error
sl_Close(g_iSockID_App);
g_iSockID_App=SL_EAGAIN;
//如果客户端正常断开的返回值为0
UART_PRINT("App client failed,lRetVal=%d\n\r",lRetVal);
}
else
{
//run command
}
}
}
Yonghua Pan:
请问能否查一下当client端关闭socket, 再连接的时候,你的sl_Accept返回的socket no是不是在递增?
你客户端关闭的时候是怎样关闭的呢?
ss sh:
回复 Yonghua Pan:
我将 BsdTcpServer()函数嵌套在while(1)中,链接PC上网络调试助手TCP client类型,第一次链接成功,断开再次链接,在接受tcp链接函数 sl_Accep报错,这个怎么解决啊!
Yonghua Pan:
回复 ss sh:
void TcpServerMultiClient(int usPort){ int serverID, socketID[7] = {-1, -1, -1, -1, -1, -1, -1}; long lNonBlocking = 1;
SlSockAddrIn_t sAddr; SlSockAddrIn_t sLocalAddr; struct SlTimeval_t timeVal; int iAddrSize; int iStatus; int iNewSockID; int i, Ret;
char buffer[1024];
sLocalAddr.sin_family = SL_AF_INET; sLocalAddr.sin_port = sl_Htons((unsigned short)usPort); sLocalAddr.sin_addr.s_addr = 0;
timeVal.tv_sec = 0; timeVal.tv_usec = 0;
serverID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
if(serverID < 0) { printf("Create TCP server socket failed\r\n"); return; }
iAddrSize = sizeof(SlSockAddrIn_t);
// binding the TCP socket to the TCP server address iStatus = sl_Bind(serverID, (SlSockAddr_t *)&sLocalAddr, iAddrSize); if( iStatus < 0 ) { sl_Close(serverID); // error printf("Bind TCP server socket failed\r\n"); return; }
// putting the socket for listening to the incoming TCP connection iStatus = sl_Listen(serverID, 0); if( iStatus < 0 ) { sl_Close(serverID); printf("Listen TCP server socket failed\r\n"); return; } printf("TCP Server Listening…\n\r");
// setting socket option to make the socket as non blocking iStatus = sl_SetSockOpt(serverID, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &lNonBlocking, sizeof(lNonBlocking)); if( iStatus < 0 ) { printf("set socket TCP server socket failed\r\n"); sl_Close(serverID); return; }
sl_SetSockOpt(serverID,SOL_SOCKET,SL_SO_RCVTIMEO, &timeVal, sizeof(timeVal));
//serverID = SL_EAGAIN;
while(1) { for(i = 0; i < 7; i ++) { if(socketID[i] < 0) { if( (socketID[i] = sl_Accept(serverID, ( struct SlSockAddr_t *)&sAddr, (SlSocklen_t*)&iAddrSize)) >= 0) { printf("Got a connection, socket id:%d\r\n", socketID[i]); iStatus = sl_SetSockOpt(socketID[i], SL_SOL_SOCKET, SL_SO_NONBLOCKING, &lNonBlocking, sizeof(lNonBlocking));
sl_SetSockOpt(socketID[i],SOL_SOCKET,SL_SO_RCVTIMEO, &timeVal, sizeof(timeVal)); } } //printf("socket id:%d\r\n", socketID[i]); if(socketID[i] > 0) { //printf("socket id:%d–i:%d\r\n", socketID[i], i);
Ret = sl_Recv(socketID[i], buffer, 1024, 0);
if(Ret > 0) { buffer[Ret] = '\0'; printf("Received packets:%s\r\n", buffer); } //else // printf("Returned value:%d\r\n", Ret); } } }}
Yonghua Pan:
回复 ss sh:
我贴了一段代码给你,这是支持多次连接的,你可以参考一下。在你的客户端关闭链接后,请注意要通知你的服务器端关闭套接字。CC3200没有能力知道套接字现在有没有断。
TI中文支持网


