参考Programming Windows TCP Sockets in C++ for the Beginners(见codeproject), socket I/O模型选择WSAAsyncSelect进行编程时,参考代码有个bug:Server端第一次连接并读取Client端发送的buffer OK, 第二次就没有FD_READ事件了。
问题相关代码
WSAAsyncSelect (s, hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT);
s(套接字)为全局变量。以上代码可以看到accept客户端连接替换的套接字与WSAAsyncSelect模型事件通知的套接字同一变量。
看看事件顺序
第一次客户端连接并发送buffer
FD_ACCEPT WSAAsyncSelect模型事件通知的套接字替换为accept客户端连接替换的套接字
FD_READ 从accept客户端连接替换的套接字读取buffer
FD_CLOSE 关闭客户端与Server的socket连接
第二次客户端连接并发送buffer
FD_ACCEPT 此时WSAAsyncSelect模型事件通知的套接字已经非法,使用accept从WSAAsyncSelect模型事件通知的套接字获取客户端连接套接字显示失败。
所以我们需要区分客户端连接替换的套接字与WSAAsyncSelect模型事件通知的套接字。
解决方案如下:
1、定义两个socket全局变量
SOCKET s; //WSAAsyncSelect模型事件通知的套接字同一变量
SOCKET c; //accept客户端连接替换的套接字
case FD_CLOSE: //Lost connection
if (c) closesocket(c);
break;
case FD_READ: //Incoming data to receive
static char buffer[80];
memset(buffer, 0, sizeof(buffer)); //Clear the buffer
recv (c, buffer, sizeof(buffer)-1, 0); //Get the text
break;
case FD_ACCEPT: //Connection request
{
char szAcceptAddr[100];
SOCKET TempSock = accept(s, (struct sockaddr*)&from, &fromlen);
c= TempSock; //Switch our old socket to the new one
break;
}

本文探讨了使用WSAAsyncSelect模型进行Socket编程时的一个常见问题:在处理客户端连接和数据接收过程中出现的FD_READ事件丢失现象。通过具体代码示例展示了问题所在,并提出了一种解决方案,即区分客户端连接套接字与事件通知套接字。
808

被折叠的 条评论
为什么被折叠?



