主题:询问一个关于异步套接字的编程问题
dazzae
[专家分:60] 发布于 2006-04-13 16:26:00
在使用异步方式探测服务器端的消息后能够收到服务器端的消息,然后输出到界面上显示出来。但是,我不希望将那个消息显示出来,我必须让我自己的函数得到那条消息,然后再对消息进行处理。如何停止异步,而让我自己的函数接收到那条消息。
急切盼望等待中……
谢谢各位大侠!
回复列表 (共3个回复)
沙发
dazzae [专家分:60] 发布于 2006-04-13 17:11:00
if(WSAAsyncSelect(clientSock, hwnd, NULL, NULL) == SOCKET_ERROR)
{
AfxMessageBox("注册网络异步事件失败!");
WSACleanup();
return;
}
send(clientSock, "PASV\r\n",6,0);
//recv info from server
do {
nRC = recv(clientSock, buf, sizeof(buf), 0);
s += buf;
}while(nRC == sizeof(buf));
//reset asynchronic mode
if(WSAAsyncSelect(clientSock, hwnd, NETEVENT, FD_READ) == SOCKET_ERROR)
{
AfxMessageBox("注册网络异步事件失败!");
WSACleanup();
return;
}
取消异步中间的那个消息我希望能够自己接收下来再处理,但是,跟踪发现其实根本得不到理想的消息,而且,原来接收过的消息这里也又再一次接收了,如下所示:
220 Serv-U FTP Server v6.0 for WinSock ready... //异步已接收
331 User name okay, need password. //异步已接收
230 User logged in, proceed. //异步已接收
227 Entering Passive Mode (192,168,1,100,8,34) //异步同样接收了,但是这是我自己希望取出来处理的啊
我觉得我明显是在发送PASV命令以前清除了异步消息的啊,怎么会继续探测到消息呢,而且,那些我本来已经接收了的消息,这里怎么会还重复接收一次呢,不明白。真是郁闷啊!
板凳
dazzae [专家分:60] 发布于 2006-04-13 17:24:00
To cancel all notification indicating that Windows Sockets should send no further messages related to network events on the socket, lEvent is set to zero.
rc = WSAAsyncSelect(s, hWnd, 0, 0);
Although WSAAsyncSelect immediately disables event message posting for the socket in this instance, it is possible that messages could be waiting in the application message queue. Therefore, the application must be prepared to receive network event messages even after cancellation.
3 楼
fucker [专家分:680] 发布于 2006-04-13 19:34:00
有个概念要清楚,异步操作是立即返回不组塞。但如果你本身发送和接收的 packet
大小就不会造成组塞呢?那它一样接收。这就是导致你上述现象的原因。其实你
这样做完全没必要。使用一个全部 BOOL 变量和一个 EVENT 配合完全可以达到目的。
如果需要处理前先设置变量。如 BOOL 变量已设置则在哪个 EVENT 上等待,处理
函数处理完成后 SetEvent(),恢复变量。
还有为什么你的代码框架是这样的?你直接
WSAAsyncSelect( socket, hWnd, NETEVENT, FD_READ|FD_WRITE|FD_CLOSE );
然后再你的 FD_READ 中 recv() 不就行了么?你要 send() 的话直接发送就好了。
如果你不想处理一些窗体消息就用 WSAEventSelect() 设置 FD_XXX 用
WSAWaitForMultipleEvents() 等待消息产生,当消息触发时 WSAEnumNetworkEvents()
判断是哪个具体事件,并做相应处理。这样即全部避免了窗体消息。或者干脆直接
使用 select() 算了。这些我好象跟你说过。
我来回复