轉自:https://blog.csdn.net/weixin_30624825/article/details/98693597
首先了解accept、AcceptEx、WSAAccept的區別 .
1. accept、WSAAccept是同步操作,AcceptEx是異步操作
2. WSAAccept函數在accept函數基礎上添加了條件函數判斷是否接受客戶端連接
3. AcceptEx是異步的,可以同時發出多個AcceptEx請求,支持重疊IO操作.
WSAAccept()
簡述
有條件地接受一個連接基於狀態函數的返回值,選擇創建或加入一個套接字組,提供QOS flowspecs,允許連接數據的轉移。
函數原型
SOCKET WSAAccept( _In_ SOCKET s, _Out_ struct sockaddr *addr, _Inout_ LPINT addrlen, _In_ LPCONDITIONPROC lpfnCondition, _In_ DWORD_PTR dwCallbackData );
參數說明
s:標識一個套接口的描述字,該套接口在listen()後監聽連接。
addr:(可選)指針,指向存放通訊層所知的連接實體地址的緩衝區。addr參數的具體格式由套接口創建時產生的地址族決定。
addrlen:(可選)指針,指向存放addr地址長度的整形數。
lpfnCondition:(可選的)用戶提供的條件函數的進程實例地址。該函數根據參數傳入的調用者信息作出接受或拒絕的決定,並通過給結果參數賦予特定的值來(可選地)創建和/或加入一個套接口組。
dwCallbackData:作爲條件函數參數返回給應用程序的回調數據。WinSock不分析該參數。
返回值
若無錯誤發生,WSAAccept()函數返回所接受套接口的描述字。
否則的話,將返回INVALID_SOCKET錯誤,應用程序可通過WSAGetLastError()來獲取相應的錯誤代碼。
附註
這個WSAAccept函數提取 等待鏈接隊列(SOCKET s)中的第一個鏈接。
如果條件函數lpfnCondition不爲NULL,則根據條件函數檢測它是否符合條件。
如果條件函數返回CF_ACCEPT,WSAAccept創建一個新的套接字。新創建的套接字和SOCKET s具有相同的屬性,包括WSAAsyncSelect或WSAEventSelect 註冊的異步事件。
如果條件函數返回CF_REJECT,WSAAccept拒絕這個連接請求。
條件函數運行在相同的線程,應儘快快速返回。
條件函數應該返回 CF_DEFER表明沒有作出如何處理這個連接請求的決定。當應用程序可以處理這個連接請求時,就可以再次調用WSAAccept,並將 CF_ACCEPT 或者 CF_REJECT作爲條件函數的返回值。
錯誤代碼
WSANOTINITIALISED 在調用本API之前應成功調用WSAStartup()。
WSAECONNREFUSED 根據條件函數的返回值(CF_REJECT)強制拒絕連接請求。
WSAENETDOWN 網絡子系統失效。
WSAEFAULT addrlen參數太小(小於sockaddr結構的大小),或者lpfnCondition並不是用戶空間的一部分。
WSAEINTR 通過WSACancelBlockingCall()函數取消(阻塞)調用。
WSAEINPROGRESS 一個阻塞WinSock調用正在進行。
WSAEINVAL WSAAccept()調用前未執行listen()調用;條件函數中的g參數非法;條件函數的返回值非法;套接口處於非法狀態。
WSAEMFILE WSAAccept()調用時排隊隊列非空,且無可用套接口描述字。
WSAENOBUFS 無可用緩衝區空間。
WSAENOTSOCK 描述字不是一個套接口。
WSAEOPNOTSUPP 所引用的套接口不是支持面向連接服務類型的。
WSATRY_AGAIN 根據條件函數的返回值(CF_DEFER) ,連接請求被推遲。
WSAEWOULDBLOCK 套接口標誌爲非阻塞,無連接請求供接受。
WSAEACCES 被推遲的連接請求超時或撤銷。