SOCKET之重疊I/O模型

首先要想再套接字上使用重疊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應該在無須遠程系統對所有的數據進行收到確認的情況下結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章