首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

select模型联接多个客户端

2014-01-01 
select模型连接多个客户端大家好,有问题请教。下面的代码是select模型服务端的代码,为什么第一段代码能连接

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);
                }
            }
        }
    }


参考下这个,能正常连接多个客户端的select模型,没有做一些错误处理,写的比较简单

热点排行