6、基于消息的异步套接字

基于消息的异步套接字

    Windows套接字在两种模式下执行I/O操作:阻塞模式和非阻塞模式。

    在阻塞模式下,在I/O操作完成前,执行操作的Winsock函数会一直等待下去,不会立即返回程序(将控制权交还给程序)。而在非阻塞模式下,Winsock函数无论如何都会立即返回。采用异步套接字,可有效改善程序的运行性能。

Windows Sockets为了支持Windows消息驱动机制,使应用程序开发者能够方便地处理网络通信,它对网络事件采用了基于消息的异步存取策略。

Windows Sockets的异步选择函数WSAAsyncSelect()提供了消息机制的网络事件选择,当使用它登记的网络事件发生时,Windows应用程序相应的窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信息。

      在上一章中编写的Chat程序中,因为接收程序放在了一个线程中,所以虽然它是阻塞的,也没有影响到主线程的运行性能。

相关的函数:

int WSAEnumProtocols(

  LPINT lpiProtocols,                   

  LPWSAPROTOCOL_INFO lpProtocolBuffer,  

  ILPDWORD lpdwBufferLength             

);

The Windows Sockets WSAEnumProtocols function retrieves information about available transport protocols.

The Windows Sockets WSAStartup function initiates use of Ws2_32.dll by a process.

int WSAStartup(

  WORD wVersionRequested,  

  LPWSADATA lpWSAData  

);

The Windows Sockets WSAAsyncSelect function requests Windows message-based notification of

network events for a socket.

int WSAAsyncSelect(

  SOCKET s,           

  HWND hWnd,          

  unsigned int wMsg,  

  long lEvent         

);

The Windows Sockets WSACleanup function terminates use of the Ws2_32.dll.

int  WSACleanup (void);

The Windows Sockets WSASocket function creates a socket that is bound to a specific

transport-service provider. 

SOCKET WSASocket(

  int af,                             

  int type,                           

  int protocol,                       

  LPWSAPROTOCOL_INFO lpProtocolInfo,  

  GROUP g,                            

  DWORD dwFlags                       

);

利用主机名实现网络访问时一个结构体:

The Windows Sockets hostent structure is used by functions to store information about a given

 host, such as host name, IP address, and so forth. An application should never attempt to

modify this structure or to free any of its components. Furthermore, only one copy of the

hostent structure is allocated per thread, and an application should therefore copy any

information that it needs before issuing any other Windows Sockets API calls.

struct hostent {

  char FAR *       h_name;

  char FAR * FAR * h_aliases;

  short            h_addrtype;

  short            h_length;

  char FAR * FAR * h_addr_list;

};

Gethostbyname

Gethostbyaddr

    每一个指针所指向的内存中存放的数据是以网络字节顺序存放的IP地址。

    在消息响应函数的申明中还是要添加WPARAMLPARAM参数,因为网络上的数据是通过这两个参数传递给消息响应函数进行处理的。

    综上所述,创建一个基于winsock2版本的异步套接字的网络聊天室程序有以下几个步骤:

1.      调用WSAStartup加载套接字库

2.      调用WSASocket创建套接字

3.     调用WSAAsyncSelect请求基于windows消息的网络事件通知

4.      创建自定义的消息响应函数,来处理捕获的网络事件

5.      在消息响应函数内部调用WSARecvFrom来处理接收到的数据

6.      调用WSASendTo处理发送数据 

7.      调用WSACleanup 去载套接字库

小结:

当前程序将消息的接收和发送放在了同一个线程中,即主线程中。如果采用先前使用过的阻塞套接字的话,程序会因为接收函数的调用导致主线程的暂停运行,就无法及时的发送消息了。但是采用异步套接字可使得发送和接收放在同一个线程中而不会有相互的影响。

如果采用异步套接字加上多线程编程,则大大会提高网络运用程序的性能。

在异步套接字中,利用了在程序初始化的时候调用了WSAAsyncSelect方法来声明程序的网络的事件有相应的自定义消息来处理,其真正的核心部分还是封装在MFC中。

参考:

[1] 孙鑫 《深入VC++

[2] MSDN

[3] http://blog.csdn.net/roger_ge/archive/2008/09/09/2903337.aspx

posted @ 2010-08-26 23:27  浪里飞  阅读(1821)  评论(0编辑  收藏  举报