ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

关于WSAAsyncSelect 的使用注意点

2021-08-02 12:04:40  阅读:297  来源: 互联网

标签:READ WSAAsyncSelect rd FD 关于 recv winsock 注意


基于MFC的消息处理,微软提供一个函数WSAAsyncSelect, 把winsock的事件通知抛到的UI线程。

其实我们在MFC中编程,代码处理大多在这个主UI线程中,类定义变量也好处理,最重要的一点是不需要考虑多线程的机制了。我见过之前的工作同事,他们就是用单独的读写线程来处理socket,然后通过sendmessage发送消息到主UI线程来进行事务处理,他们觉得还挺好用。其实这就是WSAAsyncSelect实现的机制了。

但是WSAAsyncSelect的使用需要我们注意几点,在微软的MSDN文档中有详细的描述了(https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncselect)。但真正理解的人却不多。总结一下:

 

1. WSAAsyncSelect自动就把socket置为非阻塞模式,所以在后续的读写当中会很容易碰到读写失败,但是我想要的数据(以读为例),还未读够。这时候你得通过WSAGetLastError判断是否由于WSAEWOULDBLOCK的原因,如果是的话,你得循环继续读,直到满足你的要求了;

2.WSAAsyncSelect上报FD_READ消息,但是你读的时候有可能失败,返回WSAEWOULDBLOCK的错误,是WSAAsyncSelect误报了吗? 不是,过程可能是这样的:

*WSAAsyncSelect 发现有100个字节收到了,上报FD_READ消息;

*在你的消息处理中,你第一次通过recv收了50个字节,winsock在你调用recv的时候判断是否含有数据可读,它继续发一个FD_READ到你的UI线程(现在还没出来呢)

*还是在当前的消息处理中,你又recv读了25个字节,winsock还会再发一个FD_READ

*还是在当前的消息处理中,你最后又recv读了剩下25个字节,winsock还会再发一个FD_READ

3.当你处理完这个事务之后,你还会收到3个FD_READ,但是你去读的时候,却返回WSAEWOULDBLOCK的错误了---没有数据可读啊!

所以第3点的读和第1点的读应该要分别设计的,第3点发现WSAEWOULDBLOCK时要放弃返回,第1点则要循环死读下去。

Read3()

{

int rd;

 

rd = recv(m_Sock, (char *)&cmd, sizeof(int), 0);

if(rd == 0 || rd == SOCKET_ERROR)

{

return false;

}

return true;

}

 

Read1()

{

int rd, j = 0;

while(j < bytes)

{

rd = recv(sock, pbuf+j, bytes-j, 0);

if(rd == 0 || rd == SOCKET_ERROR)

{

int errnon = WSAGetLastError();

if(errnon == WSAEWOULDBLOCK)

continue;

else

return false;

}

j += rd;

}

}

 

4.还有比较重要的一点是FD_READ的重入问题:例如对方定期在发送查询udp包,我们通过WSAAsyncSelect收到消息之后,在处理,而如果你在处理过程中进入了UI消息处理(例如,MessageBox),那么又会被后续收到的udp包,再次重入你的处理函数了,这会把你搞惨的!

 

标签:READ,WSAAsyncSelect,rd,FD,关于,recv,winsock,注意
来源: https://www.cnblogs.com/slowtech/p/15089308.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有