重疊I/O很多套接口I/O操作函數.
Winsock2提供了一組以WSA起頭函數,WSARecv/WSASend和WSARecvfrom/WSASendto.
幾個數據結果:
1)typedef struct _WSABUF{
u_long len; // 緩衝區大小.
char FAR *buf; // 緩衝區指針.
} WSABUF, FAR *LPWSABUF;
2)typedef struct _WSAOVERLAPPED{
DWORD Internal;
DWORD InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
WSAEVENT hEvent;
} WSAOVERLAPPED, *LPWSAOVERLAPPED;
WSAOVERLAPPED是OVERLAPPED結構移植來的,重疊I/O操作初始投遞I/O之間進行聯繫的機制.
前四個參數,由系統內部使用.hEvent設置特定的WSAEVENT對象即可.
3)typedef void(CALLBACK * LPWSAOVERLAPPED_COMPLETION_ROUTINE{
DWORD dwError, // 重疊操作的完成狀態;
DWORD cbTransferred, // 傳輸字節數
LPWSAOVERLAPPED lpOverlapped, //調用I/O操作時WSAOVERLAPPED結構信息:
DWORD dwFlags
};-
是Winsock2中重疊I/O回調函數指針,操作完成時自動調用該指針所指向完成函數.
參數分兩種情況,對於WSARecv/WSARecvfrom函數接收操作能立即結束
那麼dwFlags包含了調用接收函數時的lpFlags參數的信息,對於WSARend/WSASendto來說該參數暫時使用,系統設置爲0.
下面列出了四個Winsock2中的重疊I/O操作函數的定義:
(1)、 int WSARecv(
SOCKET s,
LPWSABUP lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
(2)、int WSASend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
(3)、int WSARecvFrom(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
DWORD dwFlags,
struct sockaddr FAR *lpFrom,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
(4)、int WSASendTo(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
struct sockaddr FAR *lpTo,
int iToLen,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
套接口s必須重疊套接口.直接調用socket函數或以參數dwFlags爲WSA_FLAG_OVERLAPPED參數調用WSASocket.
下面兩行代碼完成同樣套接口創建工作.(代碼略)
sock = WSASocket(AF_INEF, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
sock = socket(AF_INET, SOCK_STREAM, 0);
按照 lpOverlapped 和 lpCompletionRoutine3種不同工作狀態:
1).兩種均設爲NULL非重疊I/O操作處理,發送,接收函數.
2).lpCompletionRoutine爲NULL,調用這些I/O函數時lpOverlapped構中hEvent事件會被自動復位爲未觸發,重疊I/O操作完成被設置爲已觸發WSAWaitForMultipleEvents或者WSAGetOverlappedResult等待或論詢該事件對象的狀態.
3).lpCompletionRoutine不爲NULL,那麼hEvent參數將被忽略,完成例程傳遞信息.
調用WSAGetOverlappedResult應注意fWait參數不能設置爲TRUE 重疊數據發送/接收將工作非阻塞模式,函數調用能立即返回
1.返回0 已立即完成並且無錯誤發生.
2.返回SOCKET_ERROR,錯誤碼爲997(WSA_IO_PENDING),重疊I/O操作已成功初始化,完成後應用進程會得到系統通知.
3.返回SOCKET_ERROR,錯誤碼不是WSA_IO_PENDING重疊I/O操作初始化失敗.
調用WSAGetOverlappedResult函數來獲取指定套接口的最近一次重疊操作結構.
BOOL WSAGetOverlappedResult(
SOCKET s,
LPWSAOVERLAPPED lpOverlapped,
LPDWORD lpcbTransfer,
BOOL fWait,LPDWORD lpdwFlags
);
lpdwFlags,lpcbTransfer輸出參數外,餘均勻輸入參數.
其中s是感興趣的套接口描述字,lpOverlapped用於返回在該套接口的最近一次重疊操作時的WSAOverlapped結構數據,
lpcbTransfer輸出重疊操作傳輸字節數,lpdwFlags用於輸出操作的參數,fWait參數是否要等待事件對象lpOverlapped->hEvnet,
才能將fWait設置爲TRUE.如果無錯誤發生,返回TRUE,說明重疊操作已成功完成;否則返回FALSE,
重疊操作沒有完成,重疊操作已完成但發生了錯誤,參數設置錯誤導致重疊操作的狀態無法判斷.
http://szzhliu.blog.163.com/blog/static/35130895201072111211726/