Windows网络编程总结(二)

类别:编程语言 点击:0 评论:0 推荐:

Windows网络编程总结(二)

 

1. WinSokcet Architecture

2. 关于AcceptEx

使用此函数时,要包含头文:Mswsock.h,同时要链接:Mswsock.lib。可在源程序中加入下面的语句,这样在编译时,将自动链接Mswsock.lib。

#pragma comment(lib,” Mswsock.lib”)

 

下面是使用AcceptEx函数的示例代码:

#define STRICT

#define _WIN32_WINNT 0x0500  // Windows 2000 or later

#define WIN32_LEAN_AND_MEAN

 

#include <winsock.h>

#include <windows.h>

#include <Mswsock.h>

 

#pragma comment(lib,"Ws2_32.lib")

#pragma comment(lib,"Mswsock.lib")

 

 

int main()

{

       const int BUFSIZE = 48;

       LPFN_ACCEPTEX lpfnAcceptEx = NULL;

       GUID GuidAcceptEx = WSAID_ACCEPTEX;

       DWORD dwBytes = 0;

       SOCKET ListenSocket = INVALID_SOCKET;

       SOCKET ClientSocket = INVALID_SOCKET;

       HANDLE hCompPort = INVALID_HANDLE_VALUE;

       OVERLAPPED ol;

       char buf[BUFSIZE];

 

       // Init WinSock Lib ....

 

       ListenSocket = WSASocket(AF_IPX, SOCK_STREAM, NSPROTO_SPX, NULL, 0, WSA_FLAG_OVERLAPPED);

       ClientSocket = WSASocket(AF_IPX, SOCK_STREAM, NSPROTO_SPX, NULL, 0, WSA_FLAG_OVERLAPPED);

 

       // Bind && Listen ....

 

    // Associate the listening socket with the completion port

    CreateIoCompletionPort((HANDLE)ListenSocket, hCompPort, (u_long)0, 0);

 

 

       // Get AccpetEx Function

       WSAIoctl(ListenSocket,

              SIO_GET_EXTENSION_FUNCTION_POINTER,

              &GuidAcceptEx,

              sizeof(GuidAcceptEx),

              &lpfnAcceptEx,

              sizeof(m_WorkInfo.AcceptInfo.lpfnAcceptEx),

              &dwBytes,

              NULL,

              NULL

              );

 

       ZeroMemory(buf,BUFSIZE);

       ZeroMemory(&ol,sizeof(OVERLAPPED));

 

       // Post Accept Message

       lpfnAcceptEx(ListenSocket,

              ClientSocket,

              buf,

              0,

              sizeof(SOCKADDR_IN) + 16,

              sizeof(SOCKADDR_IN) + 16,

              &dwBytes,

              &ol

              );

}

需要注意的是,通过WSAIoctl获取AcceptEx函数指针时,只需要传递给WSAIoctl一个有效的SOCKET即可,该Socket的类型不会影响获取的AcceptEx函数指针。

如果不希望AcceptEx建立连接后等待用户发送数据,那么必须将第四个参数设为0。第5、6参数必须是对应SOCKET的地址类型的大小再加上16个字节。

为了使服务器能较好的处理用户连接请求,可采取如下两种策略:

A.                   设定两个界限值,使系统未处理的Accept操作保持在一个固定水平。推荐上限为10;

B.                   通过WSAEventSelect函数监听ListenSocket上的FD_ACCEPT事件。

当关闭完成端口时,如果还有未处理的Accepte操作,应该先关闭ListenSocket,然后在IOCP中,处理这些Accept操作(进行资源释放等),切记不要强行终止那些没有处理的Accept操作,否则会造成内存泄漏。

 

为防止恶意用户(建立连接后,不发送数据),可设置ListenSocket的SO_CONNECT_TIME属性。

 

如果希望ClientSocket具有和ListenSocket相同的属性,需要对ClientSocket调用SO_UPDATE_ACCEPT_CONTEXT。

本文地址:http://com.8s8s.com/it/it25594.htm