socket常见错误代码解析.docx
《socket常见错误代码解析.docx》由会员分享,可在线阅读,更多相关《socket常见错误代码解析.docx(13页珍藏版)》请在冰豆网上搜索。
![socket常见错误代码解析.docx](https://file1.bdocx.com/fileroot1/2022-12/14/9791af3e-edc7-4eac-b837-c57568a09fe4/9791af3e-edc7-4eac-b837-c57568a09fe41.gif)
socket常见错误代码解析
socket常见错误代码解析
Socketerror0-Directlysenderror
Socketerror10004-Interruptedfunctioncall
Socketerror10013-Permissiondenied
Socketerror10014-Badaddress
Socketerror10022-Invalidargument
Socketerror10024-Toomanyopenfiles
Socketerror10035-Resourcetemporarilyunavailable
Socketerror10036-Operationnowinprogress
Socketerror10037-Operationalreadyinprogress
Socketerror10038-Socketoperationonnon-socket
Socketerror10039-Destinationaddressrequired
Socketerror10040-Messagetoolong
Socketerror10041-Protocolwrongtypeforsocket
Socketerror10042-Badprotocoloption
Socketerror10043-Protocolnotsupported
Socketerror10044-Sockettypenotsupported
Socketerror10045-Operationnotsupported
Socketerror10046-Protocolfamilynotsupported
Socketerror10047-Addressfamilynotsupportedbyprotocolfamily
Socketerror10048-Addressalreadyinuse
Socketerror10049-Cannotassignrequestedaddress
Socketerror10050-Networkisdown
Socketerror10051-Networkisunreachable
Socketerror10052-Networkdroppedconnectiononreset
Socketerror10053-Softwarecausedconnectionabort
Socketerror10054-Connectionresetbypeer
Socketerror10055-Nobufferspaceavailable
Socketerror10056-Socketisalreadyconnected
Socketerror10057-Socketisnotconnected
Socketerror10058-Cannotsendaftersocketshutdown
Socketerror10060-Connectiontimedout
Socketerror10061-Connectionrefused
Socketerror10064-Hostisdown
Socketerror10065-Noroutetohost
Socketerror10067-Toomanyprocesses
Socketerror10091-Networksubsystemisunavailable
Socketerror10092-WINSOCK.DLLversionoutofrange
Socketerror10093-SuccessfulWSAStartupnotyetperformed
Socketerror10094-Gracefulshutdowninprogress
Socketerror11001-Hostnotfound
Socketerror11002-Non-authoritativehostnotfound
Socketerror11003-Thisisanon-recoverableerror
Socketerror11004-Validname,nodatarecordofrequestedtype
WSAEADDRINUSE(10048)Addressalreadyinuse
WSAECONNABORTED(10053)Softwarecausedconnectionabort
WSAECONNREFUSED(10061)Connectionrefused
WSAECONNRESET(10054)Connectionresetbypeer
WSAEDESTADDRREQ(10039)Destinationaddressrequired
WSAEHOSTUNREACH(10065)Noroutetohost
WSAEMFILE(10024)Toomanyopenfiles
WSAENETDOWN(10050)Networkisdown
WSAENETRESET(10052)Networkdroppedconnection
WSAENOBUFS(10055)Nobufferspaceavailable
WSAENETUNREACH(10051)Networkisunreachable
WSAETIMEDOUT(10060)Connectiontimedout
WSAHOST_NOT_FOUND(11001)Hostnotfound
WSASYSNOTREADY(10091)Networksub-systemisunavailable
WSANOTINITIALISED(10093)WSAStartup()notperformed
WSANO_DATA(11004)Validname,nodataofthattype
WSANO_RECOVERY(11003)Non-recoverablequeryerror
WSATRY_AGAIN(11002)Non-authoritativehostfound
WSAVERNOTSUPPORTED(10092)WrongWinSockDLLversion
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
常見SOCKET錯誤返回碼
WSAEINTR(10004)被中斷的系統呼叫
當以阻攔式進行的WinSock函式被WSACancelBlockingCall()中斷的時候,這個阻攔式函式會得到WSAEINTR這個錯誤訊息。
讀者要注意的是,當你的程序有用WSACancelBlockingCall去中斷阻攔式函式的時候,你必須為這個阻攔式函式寫處理WSAEINTR錯誤訊息的程序代碼,否則你的程序可能會出現些無預期的錯誤。
原則上,所有能以阻攔式進行的函式都可能會發生這個錯誤。
WSAEBADF(10009)錯誤的檔案代碼
柏克萊socket接口中,檔案描述子和socket描述子是相通的,開啟socket可以想像成開啟一個檔案。
WSAEBADF在柏克萊socket界面的意義是指錯誤的socket描述子,這個錯誤的socket描述子可能是未經開啟的socket或是以關閉的socket。
在WinSock中有個相通的錯誤代碼WSAENOTSOCK,用來指定錯誤的socket描述子。
詳細說明請參考WSAENOTSOCK部分。
WSAEACCES(10013)無此權限
對於柏克萊socket接口函式,這個錯誤發生的原因通常是開啟一個不具有開啟權限的檔案或socket。
例如在UNIX上,一般的使用者不能開啟SOCK_RAW的socket,通常是超級使用者(superuser)才有此權限。
如果一般的使用者企圖開啟SOCK_RAW的socket,將會得到這個錯誤訊息。
對於WinSockAPI函式接口,發生此錯誤的函式有二:
send()和sendto()。
當利用send()或sendto()傳送數據的時候,將目的地址設成廣播地址(broadcastaddress),但是並未呼叫setsockopt()設定SO_BROADCAST選項時便會發生WSAEACCES錯誤。
WSAEFAULT(10014)錯誤的內存地址
系統偵測出使用錯誤的內存地址。
呼叫WinSock函式時,常常會有參數是以指標的方式傳入,這個指標可能是指向一個結構,如sockaddr_in結構,或是指向一個數據緩衝區。
當程序不小心傳入一個錯誤內存未指的指針時,就會發生WSAEFAULT這個錯誤。
此外,當指針所指向的內存區塊太小的時候,也會發生這個錯誤。
WSAEINVAL(10022)參數錯誤
如果傳入不正確的參數給WinSock函式的話,會導致WSAEINVAL這個錯誤。
如果參數是一個結構的指針,此結構內容填入不正確的值,也會導致這個錯誤。
例如,shutdown()函式的how()參數只能是0、1或2,若是設定成其它數值,就會出現這個錯誤。
在網絡程序的設計中,函式和函式之間的呼叫通常有一定的順序,如過不照這個順序進行,也會出現這個錯誤。
底下是針對每個相關函式的詳細說明。
函式
錯誤發生的時機
accept()
呼叫accept()之前沒有成功呼叫listen()
bind()
已經成功呼叫bind()函式而指定stocket的名稱了
getstockname()
沒有呼叫bind()函式指定socket名稱
listen()
已經處於連接狀態或是socket沒有呼叫bind()函式指定socket名稱
recv()和recvfrom()
對於datagramsocket,socket沒有呼叫bind()函式指定IP地址、port和協議等;對於streamsocket,連接尚未建立
send()和sendto()
對於datagramsocket,socket沒有呼叫bind()函式指定IP地址、port和協議等;對於streamsocket,連接尚未建立
原則上,所有函式其參數所能設定的值有一定的範圍,或是有一些特定的值,這些函式都有可能發生這個錯誤。
WSAEMFILE(10024)太多開啟的檔案
柏克萊socket接口的解釋是開啟過多的檔案,超過檔案開啟數的限制。
在柏克萊socket將檔案和socket的開啟以檔案描述子(filedescriptor)描述。
WinSock對於socket是有別於檔案的,WSAEMFILE在WinSock的意義是開啟太多的socket。
這個程序通常發生在同一部機器中執行過多的網絡程序,以致開啟過多的socket。
另一種可以避免的錯誤是應用程序沒有正常的關閉不用的socket,以致socket資源耗盡。
WSAEWOULDBLOCK(10035)函式作用阻攔中
當函式作用是以非阻攔式進行,而此刻的函式作用再返回時其函式作用尚未完成的時候,就會出現這個錯誤。
舉例來說,假設send()以非阻攔式傳送一段數據至遠程主機,假設函式返回時得到WSAEWOULDBLOCK這個錯誤,這樣表示這一段數據不能在這一次的send()函式呼叫中傳送完。
對於connect()函式,這個錯誤表示尚未成功地連接上遠程主機,連接要求正在進行中。
若你的程序中有利用setsockopt()函式以SO_LINGER設定時限,在呼叫closesocket()時有可能出現這個錯誤。
對於異步的網絡數據函式(WSAAsyncGetXXXXByYYYY())而言,得到WSAEWOULDBLOCK錯誤,表示要查詢的網絡數據目前無法取得。
這通常是個暫時性的錯誤,應用程序可能稍後再呼叫相同的函式就會成功。
WSAEINPROGRESS(10036)有阻攔函式正在執行中
對於每個process或thread,WinSock只允許”一”個阻攔式函式的執行。
如果已有阻攔式函式正在執行,而又呼叫到WinSock函式,函式會傳回WSAEINPROGRESS的錯誤。
這個錯誤也會發生在需要長執行時間的函式,如connect()。
有一種情況是這樣:
當執行”非阻攔式”的connect()函式兩次,由於是非阻攔式的connect(),第一次的呼叫傳回WSAEWOULDBLOCK錯誤碼。
此時要求連接動作尚未完成,第二次的connect()呼叫就會得到WSAEINPROGRESS的錯誤。
我們的建議是在有可能發生這種錯誤的函式呼叫前加上WSAIsBlocking()判斷是否有阻攔式函式正在執行。
如果有的話,我們可能需要將正在進行的阻攔式函式取消掉,或是將目前想要做的事取消掉。
WSAEALREADY(10037)函式作用已完成
這個錯誤的意思在柏克萊socket界面和WinSock函式的解釋上有很大的差別。
柏克萊socket接口的解釋是函式作用已完成;在WinSock中,WSAEALREADY的意思是:
”你想要取消的異步事件已經被取消了!
”,也就是當你呼叫WSACancelAsyncRequest()試圖去取消一個異步事件時,而該事件已被取消了。
WSAENOTSOCK(10038)非法的socket
通常WinSock函式都要以socket描述子當參數傳入,如果這個socket描述子所代表的socket不是正確開啟的或是根本沒有開啟,函式就會得到WSAENOTSOCK錯誤。
原則上,只要以socket描述子當參數傳入的函式都有發生WSAENOSOCK錯誤的可能。
WSAEDESTADDRREQ(10039)需要對方地址
當你要傳送數據給遠程機器,必須指定對方的地址(和port等等),才能正確送達。
檢查看看你的應用程序是否在呼叫connect()或sendto()時,正確地填入對方的sockaddr結構。
WSAEMSGSIZE(10040)訊息太長,緩衝區無法容納
這個錯誤發生原因是由於訊息數據過大,緩衝區無法容納,這裡的緩衝區可能是使用者指定的或是系統內部用的緩衝區。
會發生這個錯誤的函式有四:
函式
錯誤發生的時機
recv()、recvform()
利用datagramsocket接收數據時,如果recv()、recvform()指定的緩衝區長度小於接收進來datagram,這時後過長的datagram會被丟棄並告訴函式WSAEMSGSIZE這個錯誤
send()、sendto()
利用datagramsocket傳送數據時,如果送出的數據緩衝區大於WinSock所能傳遞datagram的最大長度,這時send()和sendto()傳回發生WSAEMSGSIZ這個錯誤訊息
WSAEPROTOTYPE(10041)錯誤的協議型別
錯誤產生的原因是在socket()函式呼叫時指定了WinSock不支持的協議舉例來說,你不可以在steamsocket(SOCK_STREAM)設定以UDP協議傳輸(IPPRO_UDP)。
streamsocket並不支持UDP通訊協議。
如果你真的有心去測試的話,程序中故意如此呼叫socket():
hSock=socket(AF_INET,SOCK_STREAM,IPPROTO_UDP);你會發現,這樣的socket()函式呼叫會得到WSAEPROTONOSUPPORT錯誤。
這顯然不對,照理應該得到WSAEPROTOTYPE這個錯誤才對。
WSAEPROTOTYPE這個錯誤表示指定了錯誤的協議,而所指定的協議是該地址家族(協議家族)所支持的,但不適用於socket型別。
以上述的例子來看,UDP協議是屬於AF_INET這個地址家族,但是並不能用於streamsocket(SOCK_STREAMsocket)上。
WSAEPROTONOSUPPORT這個錯誤表示所指定的協議是該協議家族所不支持的,意思上和WSAEPROTOTYPE有點出入。
事實上,WSAEPROTOTYPE和WSAEPROTONOSUPPORT之間的差別是微乎其微的。
在發展網絡程序的時候,這兩種錯誤都是代表著同一種狀況--協議指定錯誤。
總之,你永遠也沒辦法試出WSAEPROTOTYPE這個錯誤。
WSAENOPROTOOPT(10042)錯誤的協議選項(option)
這個錯誤主要是針對getsockopt()和setsockopt()函式的。
這兩個函式可以以參數設定不同的選項而有不同的作用。
對於每個選項多多少少會有些限制,如有些選項只能用在streamsocket,而有些只能用在datagramsocket。
如果違反這些限制,就會發生這個錯誤。
請看下表:
SO_DONTLINGER
SO_KEEPALIVE
SO_LINGER
SO_OOBINLINE
TCP_NODELAY
datagramsocket(SOCK_DGRAM)不支持這些選項
SO_DEBUG
SO_DONTROUTE
SO_RCVBUF
SO_SNDBUF
TCP_NODELAY
有些廠商的WinSockTCP/IP協議核心不支持這些選項
SO_ACCEPTCONN
SO_ERROR
SO_TYPE
這些選項只適用於getsockopt()函式,不能作用於setsockopt()函式
WSAEPROTONOSUPPORT(10043)不支持的協議
WinSock協議核心不支持所指定的通訊協議。
舉例來說當你用socket()函式時,第二個參數指定為SOCK_STREAM,第三個參數指定為IPPROTO_ICMP,如此socket()呼叫會得到WSAEPROTONOSUPPORT這個錯誤。
WinSock1。
1版並不支持ICMP協議,所以呼叫socket()指定ICMP這個協議,就會發生錯誤。
事實上,產生WSAEPROTONPSUPPORT錯誤的狀況不只這樣,詳見WSAEPROTOTYPE。
WSAESOCKTNOSUPPORT(10044)不支援的socket型別
目前使用的WinSock版本不支持函式所指定的socket型別。
舉例來說,完全根據WinSock1.1版的規格書發展的WinSock協議核心,並不支持SOCK_RAW這個socket型別。
在呼叫socket()函式時,地址家族選AF_INET(PF_INET)而socket型別選SOCK_RAW的話,就會發生這個錯誤。
有些廠商發展的WinSock協議核心除了支持WinSock1.1版的規格書所規範之外,還提供許多不同的功能。
我們建議您在發展程序時,如果有必要用到這些額外的功能,請好好考慮一下和其它環境兼容性的問題。
WSAEOPNOTSUPP(10045)作用函式不支持此類socket
函式作用不支持目前socket型別。
舉例來說,accept()和listen()函式只能作用在連接導向的socket(streamsocket),也就是streamsocket上。
對於recv()、recvform()、send()和sendto()函式,MSG_OOB也是只能用於連接導向的socket。
WSAEPFNOSUPPORT(10046)不支持的協議家族
目前的WinSock協議核心不支持所指定的協議家族。
這個錯誤和WSAEAFNOSUPPORT很像,目前這個錯誤被WSAEAFNOSUPPORT所取代了,讀者可以參考WSAEAFNOSUPPORT說明部分。
WSAEAFNOSUPPORT(10047)不支持的地址家族
使用協議不支持指定的地址家族。
對於socket()函式,錯誤發生原因是函式轉物錯誤的參數。
對於以sockaddr結構為參數的函數,錯誤發生的原因常是網絡協議不支持sockaddr結構中(sin_family成員)指定的地址家族。
WSAEADDRINUSE(10048)地址已被指定了
所指定的”地址”正在使用中。
這裡的地址是指socket的名稱,包含三部分:
協議、port和IP地址。
這個錯誤發生的原因通常是應用程序試圖利用bind()函式去指定port時,此port已被其它應用程序所佔用了。
這種情況發生於在同一部主機上執行兩個相同性質(指定相同socket名稱)的server程序,第二的程序會因為第一個程序先佔用某個port而得到此錯誤訊息。
還有一種常見的情況就是在撰寫client程序時,利用bind()去指定socket的port,此舉常會有這個錯誤發生。
並非不能用bind()去指定socket的port,而是你無法確定程序執行的時候,所指定的port是否有其它程序正在使用。
通常很少會在client程序中呼叫bind()函式,一般的client程序都是讓系統幫你選一個適當的port。
此外,應用程序可以利用setsockopt()的SO_REUSEADDR選項,允許port可以重複使用,可是我們並不鼓勵這樣做。
這樣可能會造成TCP/IP核心在判斷應用程序上的困擾。
WSAEADDRNOTAVAIL(10049)無法指定地址
錯誤發生的原因通常是指定了該部機器不應該有的地址。
這裡的地址包含三個部分:
網絡協議、port和IP地址。
在柏克萊socket接口中,呼叫bind()時,若指定的IP地址不是本地機器該有的地址,就會出現這個錯誤。
在呼叫connect()或sendto()函式時,如果sockaddr_in結構中的sin_port填”0”,如此也會導致這個錯誤(在UNXI上是EADDRNOTAVAIL錯誤)。
對於WinSock函式,錯誤發生的時機和柏克萊socket函式類似,bind()和connect()都會導致這樣的錯誤。
對於WinSock函式,錯誤發生的時機和柏克萊socket函式類似,bind()和connect()都會導致這樣的錯誤。
WinSock1.1版的規格書中並沒有提到bind()函式會導致WSAEADDRNOTAVAIL錯誤,不過根據我們測試的結果,bind()也會導致這樣的錯誤。
WSAENETDOWN(10050)網絡出錯
下層的網絡系統發生問題,WinSock函式無法執行。
這是一個相當嚴重的問題,這會使得幾乎所有的WinSock函式呼叫失敗。
若你的WinSock函式發生錯誤,那麼請你該好好地檢查你的網絡卡,網絡卡驅動程序和你的WinSock協議核心。
WSAENETU