2024年5月11日发(作者:)

Socket之重叠IO(附单线程下重叠IO测试代码)

步骤:

1)创建一个套接字,开始在指定的端口上监听连接请求。

2)接受一个进入的连接请求。

3)为接受的套接字新建一个WSAOVERLAPPED结构,并为该结构分配一个事件对

象句柄。也将事件对象句柄分配给一个事件数组,以便稍后由

WSAWaitForMultipleEvents函数使用。

4)在套接字上投递一个异步WSARecv请求,指定参数为WSAOVERLAPPED结构。

5)使用步骤3)的事件数组,调用WSAWaitForMultipleEvents函数,并等待与重

叠调用关联在一起的事件进入"已传信"状态

6)WSAWaitForMultipleEvents函数完成后,事件数组,调用WSAResetEvent函数,

从而重设事件对象,并对完成的重叠请求进行处理.

7)使用WSAGetOverlappedResult函数,判断重叠调用的返回状态是什么.

8)在套接字上投递另一个重叠WSARecv请求.

9)重复步骤5~8.

附测试代码(采用AcceptEx 在单线程下完成)

#include

#include

#include

#pragma comment(lib,"Ws2_")

#include

#pragma comment(lib,"")

BOOL InitSocket();

#define DATA_BUFSIZE 8192

typedef struct _SOCKET_INFORMATION {

CHAR sBuffer[DATA_BUFSIZE]; //发送缓冲区

CHAR rBuffer[DATA_BUFSIZE]; //接收缓冲区

CHAR IpBuffer[256];

WSABUF SendBuf;

WSABUF RevBuf;

SOCKET Socket;

DWORD nSend;

WSAOVERLAPPED rOverlapped;

WSAOVERLAPPED sOverlapped;

} SOCKET_INFORMATION;

void printErr(int Errid);

void main(int argc, char* argv[])

{

DWORD EventTotal=0;

SOCKET_INFORMATION* SockArray[WSA_MAXIMUM_WAIT_EVENTS]; //保存的指针

WSAEVENT sEventArray[WSA_MAXIMUM_WAIT_EVENTS];

WSAEVENT rEventArray[WSA_MAXIMUM_WAIT_EVENTS];

SOCKET ListenSocket,AcceptSocket;

SOCKADDR_IN addr;

DWORD Flags;

DWORD RecvBytes;

if(!InitSocket())

{

printf("Init Socket ");

}

printf("");

printf("Step1 Start winsock and set up a listening socket");

ListenSocket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPP

ED);

if(INVALID_SOCKET==ListenSocket)

{

printf("Create ");

return;

}

_addr.s_addr=htonl(INADDR_ANY);

_family=AF_INET;

_port=htons(5150);

if(SOCKET_ERROR==bind(ListenSocket,(SOCKADDR*)&addr,sizeof(addr)))

{

printf("bind ip ");

return;

}

printf("bind ip ");

if(SOCKET_ERROR==listen(ListenSocket,5))

{

printf("listen port ");

return;

}