请问一下socket中select模型的有关问题
请教一下socket中select模型的问题
写了一个select非阻塞的服务器端程序,但是同时启动2个客户端去连接的话会出现问题。2个客户端都可以连接成功,但是只有第二个连接的客户端发送的信息可以被正确接收到,第一个客户端发送的消息,一直出错,错误号是10035,即WSEAWOULDBLOCK,,,我很奇怪为什么会一直都无法接收。还有很多其他的问题,不一一叙述,我没自己写客户端程序,使用的是TCP&UDP测试工具进行测试的,下面上代码,望各位能指点一二。
------解决思路----------------------
写了一个select非阻塞的服务器端程序,但是同时启动2个客户端去连接的话会出现问题。2个客户端都可以连接成功,但是只有第二个连接的客户端发送的信息可以被正确接收到,第一个客户端发送的消息,一直出错,错误号是10035,即WSEAWOULDBLOCK,,,我很奇怪为什么会一直都无法接收。还有很多其他的问题,不一一叙述,我没自己写客户端程序,使用的是TCP&UDP测试工具进行测试的,下面上代码,望各位能指点一二。
WSADATA Wsadata;
SOCKET Server;
SOCKET Client;
SOCKADDR_IN serverAddr;
SOCKADDR_IN clientAddr;
//保存所有客户端socket的数组
vector<SOCKET> clientSockets;
int index = 0;
FD_SET ReadSet;
//初始化环境
if (WSAStartup(MAKEWORD(2, 1), &Wsadata) != 0)
{
fprintf(stderr, "Init socket failed, error: %d\n", GetLastError());
WSACleanup();
return -1;
}
Server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (Server == INVALID_SOCKET)
{
fprintf(stderr, "Create socket failed, error: %d\n", GetLastError());
closesocket(Server);
WSACleanup();
return -1;
}
//设置为非阻塞模式
unsigned long mode = 1;
if (ioctlsocket(Server, FIONBIO, &mode) != 0)
{
return -1;
}
//设置
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888);
serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//绑定
int ret = bind(Server, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR_IN));
if (ret != 0)
{
fprintf(stderr, "Bind socket failed, error: %d\n", GetLastError());
closesocket(Server);
WSACleanup();
return -1;
}
printf("绑定成功...\n");
//监听
ret = listen(Server, 10);
if (ret != 0)
{
fprintf(stderr, "listen socket failed, error: %d\n", GetLastError());
closesocket(Server);
WSACleanup();
return -1;
}
printf("启动监听...\n");
while (1)
{
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&ReadSet);
for (int i = 0; i < index; i++)
{
//将所有的客户端放入集合中
FD_SET(clientSockets[i], &ReadSet);
}
//将服务器的socket放入集合中
FD_SET(Server, &ReadSet);
if (select(0, &ReadSet, NULL, NULL, &tv) == SOCKET_ERROR)
{
fprintf(stderr, "select error: %d\n", GetLastError());
closesocket(Server);
WSACleanup();
return -1;
}
if (FD_ISSET(Server, &ReadSet))
{
int len = sizeof(clientAddr);
//接收
Client = accept(Server, (SOCKADDR*)&clientAddr, &len);
if (Client != INVALID_SOCKET)
{
//将已经连接的客户端保存到数组中
clientSockets.push_back(Client);
index++;
printf("连接成功.\n");
}
else
{
continue;
}
}//end if
for (int i = 0; i < clientSockets.size(); ++i)
{
if (FD_ISSET(clientSockets[i], &ReadSet))
{
Sleep(1);
char buf[256];
memset(buf, 0, sizeof(buf));
int ret = recv(Client, buf, sizeof(buf)-1, 0);
if (ret == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
continue;
}
else
{
fprintf(stderr, "recv error : %d\n", GetLastError());
closesocket(clientSockets[i]);
clientSockets[i] = NULL;
index--;
return -1;
}
}
if (ret == 0)
{
closesocket(clientSockets[i]);
clientSockets.erase(clientSockets.begin() + i);
i--;
index--;
printf("断开连接.\n");
continue;
}
printf("接受信息内容 :%s\n", buf);
}//end if
}//end for
//将获得的消息存储在消息队列中
}
//关闭socket,清理环境
closesocket(Server);
closesocket(Client);
WSACleanup();
return -1;
------解决思路----------------------
for (int i = 0; i < index; ++i)
{
if (FD_ISSET(clientSockets[i], &ReadSet))
{
Sleep(1);
char buf[256];
memset(buf, 0, sizeof(buf));
int ret = recv(Client, buf, sizeof(buf)-1, 0);
if (ret == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
continue;
}
else
{
fprintf(stderr, "recv error : %d\n", GetLastError());
closesocket(clientSockets[i]);
clientSockets[i] = NULL;
index--;
return -1;
}
}
if (ret == 0)
{
closesocket(clientSockets[i]);
clientSockets.erase(clientSockets.begin() + i);
i--;
index--;
printf("断开连接.\n");
continue;
}
printf("接受信息内容 :%s\n", buf);
}//end if
}//end for
//put it at the end, every sockets in the vector were put into the fd set
if (FD_ISSET(Server, &ReadSet))
{
int len = sizeof(clientAddr);
//接收
Client = accept(Server, (SOCKADDR*)&clientAddr, &len);
if (Client != INVALID_SOCKET)
{
//将已经连接的客户端保存到数组中
clientSockets.push_back(Client);
index++;
printf("连接成功.\n");
}
else
{
continue;
}
}//end if