WSAAsyncSelect注意的地方

2017-08-10

使用WSAAsyncSelect函数注意的地方

1.调用该函数后,套接字被设备子为非阻塞模式,要想恢复为阻塞模式,必须再次调用该函数,取消掉注册过的事件,再调用ioctlsocket 设为阻塞模式。

2.消息函数的wParam参数为事件发生的套接字,LParam对应错误消息和相应的事件,可以调用宏WSAGETSELECTERROR(lParam),WSAGETSELECTEVENT(lParam)。

3.多次调用WSAAsyncSelect函数在同一个套接字上注册不同的事件(多次调用采用同样或者不同样的消息),最后一次调用将取消掉前面注册的事件。

4.使用accept()函数建立的套接字与监听套接字具有同样的属性,也就是说,在监听套接字上注册的事件同样会应用于建立连接的套接字,但是我们一般会在监听套接字建立连接后重新为其注册事件。

5.为一个FD_READ网络事件不要多次调用recv()函数,如果应用程序为一个FD_READ网络事件调用多个recv()函数,会使得该应用程序收到多个FD_READ网络事件。应用程序不必再受到FD_READ消息时,读取所以可读的数据,每收到一次网络事件,调用一次recv()函数是恰当的。

6.使用FD_CLOSE事件来判断套接字是否已经关闭,错误代码指示套接字是从容关闭还是硬关闭,错误码为0,代表从容关闭,若错误码为WSAECONNERESET,则为硬关闭。如果套接字从容关闭,数据全部接收,应用程序会收到FD_CLOSE指出虚电路关闭,它不会收到FD_READ消息来表明这个状态,调用closesocket()不会投递FD_CLOSE事件。

发生网络事件的条件

1.FD_READ。

  • 调用recv或者recvfrom函数后,仍然有数据可读。
  • 调用WSAAsyncSelect有数据可读。

2.FD_WRITE

  • 当调用WSAAsyncSelect函数时,如果调用能够发送数据。
  • 调用connect或者accept函数后,当连接已经建立时。
  • 调用send或者sendto,返回WSAWOULDBLOCK错误码,再次调用send或者sendto函数可能成功时。

3.FD_CLOSE

  • 当调用WSAAsyncSelect函数时,套接字连接关闭时。
  • 对方执行从容关闭后,没有数据可读时,如果数据已经到达并等待读取,FD_CLOSE事件不会被发送,直到所有数据都被接收。
  • 调用shutdown函数执行从容关闭,对方应答FIN后,此时无数据可读。
  • 对方结束了连接,并且lparam包含WSAECONNRESET错误时。

优势

该模型的优势在于使用了基于windows消息的处理方式,FD_CLOSE消息保证了数据全部接受,从容关闭客户端和服务端的连接。

不足

必须建立窗口,调用WSAAsyncSelect函数后,套接字被设为非阻塞模式,相关调用不一定能成功返回,必须要对相关调用的返回做处理。



注明:本文章属于转载,仅供行业人员学习交流使用,文章版权属于原创作者,在此向原创者致敬,感谢原创作者为大家学习交流提供精品内容。

站方声明:IThao123是为广大互联网从业者免费提供学习交流的平台,如果侵犯了原创著作权,请联系站方删除,给你带来不便,深表歉意。

顶部