SOCKET之重叠I/O模型

来源:互联网 发布:真人rpg游戏发展数据 编辑:程序博客网 时间:2024/04/30 14:52

首先要想再套接字上使用重叠I/O模型,首先必须使用WSA_FLAG_OVERLAPPED 这个标志创建套接字

WSASocket(AF_INET,SOCKET_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);

如果创建套接字的时候使用socket 而不是WSASocket函数那默认会设者WSA_FLAG_OVERLAPPED标志

随后将一个WSAOVERLAPPED于win32事件对象相连,关联后的事件对象会立即返回,一般返回SOCKET_ERROR错误,使用WSAGetLastError函数获得错误状态的报告为I/O操作正在进行,应用程序要等候于wsaoverlapped结构对应的事件对象了解一个重叠I/O造作何时完成,可绑定的方法有:

■ W S A S e n d
■ W S A S e n d To
■ W S A R e c v
■ W S A R e c v F r o m
■ W S A I o c t l
■ A c c e p t E x
■ Tr n a s m i t F i l e

 typedef struct _WSAOVERLAPPED{

DWORD internal;

DWORD internalhigh;

DWORD Offset;

DWORD OffsetHigh; //均由系统设定

WSAEVENT hEvent; //表示I/O操作完成的事件WSACreateEvent()

};WSAOVERLAPPED, FAR* LPWSAOVERLAPPED;

I/O重叠模式下的的接收数据函数为

int WSARecv(

SOCKET s, //感兴趣的SOCKET

LPWSABUF lpBuffers, //接收缓冲区

DWORD dwBufferCount, //数组中WSABUF结构的数量

LPDWORD lpNumberOfBytesRevcd, //接收到的字节数

LPDWORD lpFlags, //于recv函数中相同

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine //完成例程中用到的函数

);

WSASend函数与其类似,如果返回值为WSA_IO_PENDING说明WSARecv操作成功但I/O要等到绑定的事件发生后才能完成,所有的I/O处理由系统去做,我们就等着拿数据--#什么时候完成就靠我们下面的函数了

DWORD WSAWaitForMultipleEvents(

DWORD cEvents, //等待事件的总数量最多为64个

const WSAEVENT* lphEvents, //事件数组的指针

BOOL fWaitAll,//为TRUE时等所有事件发生时才返回,设置为FALSE时,只要有一个事件发生就返回

DWORD dwTimeout, //超时事件为0时立即返回,为WSA_INFINITE时候只有等到事件成功才会返回

BOOL fAlertable //完成例程中用到的参数

);

得到事件通知后我们要来查询一下重叠操作的结果

BOOL WSAGetOverlappedResult(

SOCKET s,

LPWSAOVERLAPPED lpOverlapped, //想要查询结果的那个重叠结构

LPDWORD lpcbTransfer, //重叠操作世界接收的字节数

BOOL fWait, //设置为TRUE,除非重叠操作完成,否则函数不会返回 FALSE时函数会立即返回,如果重叠操作仍然是挂起的拿函数就会返回FALSE错误为WSA_IO_INCOMPLETE

LPDWORD lpdwFlags //负责接收结果标志

);

最后介绍下下AcceptEx函数

BOOL AcceptEx(

SOCKET sListenSocket,

SOCKET sAcceptSocket, //另一个负责接受的套接字

PVOID lpOutputBuffer, //l p O u t p u t B u ff e r参数指定的是一个特殊的缓冲区,因为它要负责三种数据的接收:服务器的本地地址,客户机的远程地址,以及在新建连接上发送的第一个数据块。

DWORD dwReceiveDataLength, //保留多大空间用作数据接受,如果是0则表示不接收数据部分

DWORD dwLocalAddressLength, //多大空间保存本地地址信息指定的缓冲区至少应比创送协议允许的最大地址长度大16个字节,如TCP下为SOCKET_IN结构的长度+16

DWORD dwRemoteAddressLength, //多大空间保存远程地址信息

LPDWORD lpdwBytesReceived, //于返回接收到的实际数据量以字节为单位如果返回ERROR_IO_JPENDING,这个参数就不会设置,只有在同步的情况下他才有效

LPOVERLAPPED lpOverlapped

)

使用RecvEx函数要添加mswsock.h文件和链接mswsock.lib文件

开饭咯.....

回来咯.....想起个好玩的函数还没说

Tr a n s m i t F i l e是微软专有的Wi n s o c k扩展,它允许从一个文件中传输高性能数据。这是非常有效的,因为整个数据传输可在内核模式中进行。也就是说,如果你的应用从指定的文件中读取一堆数据,然后用s e n d或W S A S e n d时,涉及到“用户模式到内核模式传输”的发送调用就有若干个。有了Tr a n s m i t F i l e,整个读取和发送数据的进程就可在内核模式中进行。该函数的定义如下:

BOOL TransmitFile(

SOCKET hSocet,

HANDLE hFile, //打开的文件句柄

DWORD nNumberOfBytesToWrite, //发送的数据大小0为全部

DWORD nNumberOfBytesPerSend, //每次发送的数据大小

LPVOERLAPPED lpOverlaped, //重叠结构

LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, //传输之前和传输之后准备发送的数据

DWORD dwFlags //标志说明如下

);

typedef struct _TRANSMIT_FILE_BFFERS{

PVOID Head; //传输之前准备发送的数据

DWORD HeadLength;

PVOID Tail; //传输之后准备发送的数据

DWORD TailLength;

}TRANSMIT_FILE_BUFFERS;

TF_DISCONNETCT            数据发送完毕之后,开始执行套接字关闭

T F _ R E U S E _ S O C K E T 允许套接字句柄再次作为客户机套接字用于A c c e p t E x中

T F _ U S E _ D E FA U LT _ W O R K E R 表明传输应该在系统默认线程场景中进行。特别有利于长文件传输
T F _ U S E _ S Y S T E M _ T H R E A D 表明传输应该在系统线程场景中进行。同样有利于长文件传输
T F _ U S E _ K E R N E L _ A P C 表明“内核异步进程调用”(A P C)应该对文件传输进行处理。如果把指定文件读入缓冲区只需要一次读取,该标志便可提供一个重要的性能提升

T F _ W R I T E _ B E H I N D 表明Tr a n s m i t F i l e应该在无须远程系统对所有的数据进行收到确认的情况下结束

原创粉丝点击