Socket WSAAsyncSelect模型值得注意的一个地方
2011-01-14 18:47
190 查看
参考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 (s, hwnd, 1045, FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT);
case FD_CLOSE: //Lost connection MessageBeep(MB_ICONERROR); //Clean up if (s) closesocket(s); WSACleanup(); SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Connection to Remote break; case FD_READ: //Incoming data to receive char buffer[80]; memset(buffer, 0, sizeof(buffer)); //Clear the buffer recv (s, buffer, sizeof(buffer)-1, 0); //Get the text GetTextandAddLine(buffer, hwnd, ID_EDIT_DATA); //Display it break; case FD_ACCEPT: //Connection request { MessageBeep(MB_OK); SOCKET TempSock = accept(s, (struct sockaddr*)&from, &fromlen); s = TempSock; //Switch our old socket to the new one char szAcceptAddr[100]; wsprintf(szAcceptAddr, "Connection from [%s] accepted.", inet_ntoa(from.sin_addr)); SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)szAcceptAddr); } break;
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;
}
相关文章推荐
- 关于Socket和IOCP的一些值得注意的地方
- 【转】关于Socket和IOCP的一些值得注意的地方
- 【转】关于Socket和IOCP的一些值得注意的地方
- socket server select模型值得注意的地方
- *关于Js中this值得注意的一个地方
- android socket 编程 值得注意的地方
- 今天第一次改Makefile 有一个值得注意的地方
- 关于Socket和IOCP的一些值得注意的地方
- 关于Socket和IOCP的一些值得注意的地方
- 关于Socket和IOCP的一些值得注意的地方
- 关于Socket和IOCP的一些值得注意的地方
- 关于Socket和IOCP的一些值得注意的地方
- 给自己一个有鱼的地方
- DataList等控件嵌套绑定的一个需要注意的地方
- PHP 不可思议的一个地方
- handlersocket使用 第一章 基本语法和一个简单示例
- 推荐广州天河龙口西的一个吃饭好地方
- 用Python socket实现一个简单的http服务器(post 与get 的区别)、CGIHTTPServer 简单应用
- 一个Socket网络编程的简单例子
- 再发一个HTML5+WebSocket+PHP多进程 多人在线小蝌蚪游戏[强烈推荐]