Windows套接字AcceptEx函式接受一個新的連線,返回本地和遠程地址,並接收由客戶端應用程式傳送的第一塊數據。Windows 95/98不支持AcceptEx函式。
基本介紹
- 中文名:AcceptEx
- 返回:遠程地址本地
- 接收:客戶端應用程式傳送的第一塊數據
- 不支持:AcceptEx函式
簡介,注意,參數,備註,
簡介
平台SDK:Windows套接字
AcceptEx
注意
此函式是一個Microsoft特定的擴展,Windows Sockets規範。有關詳細信息,請參閱Microsoft擴展和Windows Sockets 2。
BOOL AcceptEx(
IN SOCKET sListenSocket,
IN SOCKET sAcceptSocket,
IN PVOID lpOutputBuffer,
IN DWORD dwReceiveDataLength,
IN DWORD dwLocalAddressLength,
IN DWORD dwRemoteAddressLength,
OUT LPDWORD lpdwBytesReceived,
IN LPOVERLAPPED lpOverlapped
);
參數
sListenSocket
[in]偵聽套接字。伺服器應用程式在這個套接字上等待連線。
sAcceptSocket
[in]將用於連線的套接字。此套接字必須不能已經綁定或者已經連線。
lpOutputBuffer
[in]指向一個緩衝區,該緩衝區用於接收新建連線的所傳送數據的第一個塊、該伺服器的本地地址和客戶端的遠程地址。接收到的數據將被寫入到緩衝區0偏移處,而地址隨後寫入。 該參數必須指定,如果此參數設定為NULL,將不會得到執行,也無法通過GetAcceptExSockaddrs函式獲得本地或遠程的地址。
dwReceiveDataLength
[in]lpOutputBuffer位元組數,指定接收數據緩衝區lpOutputBuffer的大小。這一大小應不包括伺服器的本地地址的大小或客戶端的遠程地址,他們被追加到輸出緩衝區。如果dwReceiveDataLength是零,AcceptEx將不等待接收任何數據,而是儘快建立連線。
dwLocalAddressLength
[in]為本地地址信息保留的位元組數。此值必須比所用傳輸協定的最大地址大小長16個位元組。
dwRemoteAddressLength
[in]為遠程地址的信息保留的位元組數。此值必須比所用傳輸協定的最大地址大小長16個位元組。 該值不能為0。
dwBytesReceived
[out]指向一個DWORD用於標識接收到的位元組數。此參數只有在同步模式下有意義。如果函式返回ERROR_IO_PENDING並在遲些時候完成操作,那么這個DWORD沒有意義,這時你必須獲得從完成通知機制中讀取操作位元組數。
lpOverlapped
[in]一個OVERLAPPED結構,用於處理請求。此參數必須指定,它不能為空。
如果沒有錯誤發生,AcceptEx函式成功完成並返回TRUE。
如果函式失敗,AcceptEx返回FALSE。可以調用WSAGetLastError函式獲得擴展的錯誤信息。如果WSAGetLastError返回ERROR_IO_PENDING,那么這次行動成功啟動並仍在進行中。
備註
*在AcceptEx結合了幾個socket函式的功能,acceptEx函式當成功時執行三項任務:
1. 一個新的連線被接受。
2. 返回連線的本地和遠程地址。
3. 得到遠程傳送的第一個數據塊。
*較accept函式而言,程式使用AcceptEx可以更快連線到一個套接字。
*輸出緩衝區lpOutputBuffer存放內容包括:接收到的第一塊數據、本地套接字地址(伺服器)和遠程套接字地址(客戶端)。
使用單一的緩衝區可以提高性能,當使用AcceptEx時,必須使用GetAcceptExSockaddrs函式將輸出緩衝區的內容解析到三個不同部分的緩衝區 (data, local socket address, and remote socket address)。 在windows XP 及隨後版本中,當 AcceptEx函式完成操作並且SO_UPDATE_ACCEPT_CONTEXT選項在被接受的socket中被設定時, socket相關的本地地址(local address )可以使用getsockname函式獲得。類似的,與被接受socket 相關的遠程端地址(the remote address)可以使用getpeername函式獲得。
*本地和遠程地址緩衝區的大小必須比使用傳輸協定的sockaddr地址大16個位元組,是因為是以內部格式寫入。例如,一個SOCKADDR_IN大小(TCP / IP協定的地址結構)是16個位元組。因此,本地和遠程地址緩衝區的大小必須指定至少32個位元組。
*AcceptEx函式使用的重疊I / O。與使用accept相比,使用AcceptEx能以相對較少的執行緒數量處理大量的客戶。如同所有的Win32重疊函式,Win32事件或完成連線埠都可用來作為完成通知機制。
AcceptEx和accept函式的另一個主要區別是,AcceptEx函式需要調用者提供兩個套接字參數:
一個指定監聽套接字。
一個指定接受連線的套接字。
該sAcceptSocket參數必須是一個已經打開的socket,不能是已綁定或者是已連線的socket。
*GetQueuedCompletionStatus函式或GetOverlappedResult函式的lpNumberOfBytesTransferred參數表明該請求接收到的位元組數。
當此操作成功完成,sAcceptSocket可以使用,但只限下列功能:
ReadFile
WriteFile
傳送
recv
關閉套接字
注意:如果調用TransmitFile函式時,指定TF_DISCONNECT和TF_REUSE_SOCKET標誌,指定套接字的已返回未綁定,未連線的狀態。然後,您可以使用該套接字句柄作為AcceptEx函式的sAcceptSocket參數。但該套接字不能作為ConnectEx函式的參數。
當AcceptEx函式返回時,sAcceptSocket是一個已連線套接字。如未指定SO_UPDATE_ACCEPT_CONTEXT屬性,sAcceptSocket不繼承與sListenSocket參數相關套接字的屬性。使用Setsockopt函式來設定SO_UPDATE_ACCEPT_CONTEXT選項,指定sAcceptSocket的套接字句柄和sListenSocket作為選項的值(specifying sAcceptSocketas the socket handle and sListenSocketas the option value) 。
例如:
error= setsockopt(sAcceptSocket,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char*)&sListenSocket,
sizeof(sListenSocket));
如果提供了數據接收緩衝區(dwReceiveDataLength!=0),異步操作將在連線建立並且接收到第一塊數據後完成。使用getsockopt的SO_CONNECT_TIME選項來檢查連線是否已經接受。如果它已被接受,您可以判斷連線建立多久。該選項的返回值是套接字連線已建立的秒數。如果套接字未連線,getsockopt返回0xFFFFFFFF。應用程式通過檢查SO_CONNECT_TIME並結合檢查異步操作是否完成,可以確定是否連線已建立了一段時間但沒有收到任何數據。我們建議您終止這些連線,可以通過關閉連線強制AcceptEx完成操作,並返回一個錯誤狀態。
例如:
int seconds;
BYTE opt = sizeof(seconds);
error == getsockopt(sAcceptSocket,SOL_SOCKET,SO_CONNECT_TIME,
(char*)&seconds,(int)&opt);
if(error= NO_ERROR){
printf(“getsockopt(SO_CONNECT_TIME)失敗:%d\ N”的,WSAGetLastError());
exit(1);
}
Notes for ATM