select模型连接多个客户端
大家好,有问题请教。
下面的代码是select模型服务端的代码,为什么第一段代码能连接多个客户端,而改成第二段代码就不行了,只能连接一个,是哪里出问题了。求指教。
fd_set fdSocket ; // 所有可用套节字集合
FD_ZERO(&fdSocket );
FD_SET(s , &fdSocket);
while (1)
{
// (3)
fd_set fdRead = fdSocket;
fd_set fdWrite = fdSocket;
int ret = select(0, & fdRead, &fdWrite , NULL, NULL);
//(4)
if (ret > 0)
{
for (int i = 0; i < (int )fdSocket. fd_count; i ++)
{
if (FD_ISSET (fdSocket. fd_array[i ], &fdRead))
{
if (fdSocket .fd_array[ i] == s )
{
if (fdSocket .fd_count < FD_SETSIZE)
{
sClient = accept (s, (SOCKADDR*)&addrClient , &ilen);
FD_SET(sClient , &fdSocket);
printf(" 客户端的 IP地址为: %s,端口为 : %d\n",
inet_ntoa(addrClient .sin_addr), ntohs(addrClient .sin_port));
}
else
{
printf(" 客户端太多了 ");
continue;
}
}
else
{
char recvBuf [512];
memset(recvBuf , 0, 512);
if (recv (fdSocket. fd_array[i ], recvBuf, sizeof (recvBuf), 0) == SOCKET_ERROR)
{
closesocket(fdSocket .fd_array[ i]);
//printf(" 关闭\n");
FD_CLR(fdSocket .fd_array[ i], &fdSocket);
continue;
}
printf("recv() data from client: %s\n", recvBuf);
}
}
else if (FD_ISSET(fdSocket.fd_array[i], &fdWrite))
{
char sendBuf[512];
memset(sendBuf, 0, 512);
strcpy(sendBuf, "hello");
if (send(fdSocket.fd_array[i], sendBuf, sizeof(sendBuf), 0) == SOCKET_ERROR)
{
closesocket(fdSocket .fd_array[ i]);
//printf(" 关闭\n");
FD_CLR(fdSocket .fd_array[ i], &fdSocket);
continue;
}
}
}
}
else
{
printf(" Failed select() \n" );
break;
}
}
fd_set fdSocket ; // 所有可用套节字集合
FD_ZERO(&fdSocket );
FD_SET(s , &fdSocket);
while (1)
{
// (3)
fd_set fdRead = fdSocket;
fd_set fdWrite = fdSocket;
int ret = select(0, & fdRead, &fdWrite , NULL, NULL);
//(4)
if (ret > 0)
{
if (FD_ISSET(s, &fdRead))
{
if (fdSocket .fd_count < FD_SETSIZE)
{
sClient = accept (s, (SOCKADDR*)&addrClient , &ilen);
FD_SET(sClient , &fdSocket);
printf(" 客户端的 IP地址为: %s,端口为 : %d\n",
inet_ntoa(addrClient .sin_addr), ntohs(addrClient .sin_port));
}
else
{
printf(" 客户端太多了 ");
continue;
}
}
for (int i = 0; i < (int )fdSocket. fd_count; i ++)
{
if (FD_ISSET (fdSocket. fd_array[i ], &fdRead))
{
char recvBuf [512];
memset(recvBuf , 0, 512);
if (recv (fdSocket. fd_array[i ], recvBuf, sizeof (recvBuf), 0) == SOCKET_ERROR)
{
closesocket(fdSocket .fd_array[ i]);
//printf(" 关闭\n");
FD_CLR(fdSocket .fd_array[ i], &fdSocket);
continue;
}
printf("recv() data from client: %s\n", recvBuf);
}
else if (FD_ISSET(fdSocket.fd_array[i], &fdWrite))
{
char sendBuf[512];
memset(sendBuf, 0, 512);
strcpy(sendBuf, "hello");
if (send(fdSocket.fd_array[i], sendBuf, sizeof(sendBuf), 0) == SOCKET_ERROR)
{
closesocket(fdSocket .fd_array[ i]);
//printf(" 关闭\n");
FD_CLR(fdSocket .fd_array[ i], &fdSocket);
continue;
}
}
}
}
else
{
printf(" Failed select() \n" );
break;
}
}
[解决办法]
个人理解:
第二个程序中,
for循环第一次处理的还是监听套接字s,在其上执行recv出错,所以就把这个s给关闭掉了
[解决办法]
调试过,recv的时候把socket s给关闭了,导致第二个客户端连接的时候就无法监听这个socket了
[解决办法]
FD_SET fdRead;
FD_SET fdWrite;
vector<SOCKET> vecSocketInfo;
while (TRUE)
{
//zero the set before select
FD_ZERO(&fdRead);
FD_ZERO(&fdWrite);
//set the socket to the set
FD_SET(listeningSocket, &fdRead);
for (int i = 0; i < (int)vecSocketInfo.size(); i ++)
{
FD_SET(vecSocketInfo[i], &fdRead);
FD_SET(vecSocketInfo[i], &fdWrite);
}
//select
if (select(0, &fdRead, &fdWrite, NULL, NULL) == SOCKET_ERROR)
{
printf_s("Socket Error!\n");
break;
}
if (FD_ISSET(listeningSocket, &fdRead))
{
int clientAddrLen = sizeof(clientAddr);
newConnection = accept(listeningSocket, (SOCKADDR*)&clientAddr, &clientAddrLen);
ioctlsocket(newConnection, FIONBIO, &NonBlock);
vecSocketInfo.push_back(newConnection);
}
for (int i = 0; i < (int)vecSocketInfo.size(); i ++)
{
if (FD_ISSET(vecSocketInfo[i], &fdRead))
{
printf_s("Read message from socket%d\n", i);
//accept new connection
char sRecvBuf[256] = "";
if (recv(vecSocketInfo[i], sRecvBuf, sizeof(sRecvBuf), 0) > 0)
{
printf_s("%s\n", sRecvBuf);
}
else
{
closesocket(vecSocketInfo[i]);
vecSocketInfo.erase(vecSocketInfo.begin()+i);
}
}
}
}