常见socket错误返回码.docx
《常见socket错误返回码.docx》由会员分享,可在线阅读,更多相关《常见socket错误返回码.docx(17页珍藏版)》请在冰点文库上搜索。
常见socket错误返回码
常见socket错误返回码
常见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协定核心。
WSAENETUNREACH(10051)无法连上指定的网路
在柏克莱socket介面中,这个错误的意思是无法和对方网路系统取得联系。
在WinSock1。
1规格中,WSAENETUNREACH相通于柏克莱socket介面中的ETHOSTUNREACH。
WSAENETRESET(10052)网路已被重新设定
对方主机出错而重新开机。
在本地主机呼叫和传送资料有关的函式就会得到这个错误。
对于setsockopt()函式,这个错误发生的原因在于试图设定SO_KEEPALIVE于逾时(timeout)的连接。
WSAECONNABORTED(10053)中断连接
在连接建立后,当有某种原因导致TCP/IP协定核心不断地重送资料,而且都重送失败的时候,TCP/IP协定将连接中断。
此时,应用程式就会收到WSACONNABORTED这个错误。
WSAECONNRESET(10054)连结已被对方重新设定
连结已被对方系统强迫中断了。
TCP/IP协定核心如果侦测出streamsocket的连接发生问题的话,它会传一个表示连接重设(reset)的讯息给对方。
此时对方程式会得到WSAECONNRESET的错误讯息。
WSAENOBUFS(10055)缓冲区过小
WinSock核心无法配置足够的缓冲区,无法执行该程式。
这个错误的发生和整个Windows系统资源有关。
如果整个Windows本身可用的资源就很少,所能同时执行的程式也少。
也有可能是执行了"不良"的应用程式,没有正常的使用和归还系统资源(如记忆体)。
或是某些应用程式的不正常关闭,也会占用系统资源。
WSAEISCONN(10056)socket已经连接
网路函式通常会有一定的呼叫顺序,有的函式呼叫成功后便不能再呼叫,否则会出现错误。
当连接建立时,client程式呼叫()成功,而server程式呼叫accept()成功。
此时若client程式再呼叫一次connect()函式的话,会得到WSAEISCONN这个错误,表示该socket已经处于连接状态了。
如果client程式呼叫listen()函式的话也会出现这个错误,表示不应该在此时呼叫这个函式。
对于server程式,如果socket已经处于连接状态,程式呼叫connect()函式的话,也会得到WSAEISCONN这个错误。
上述错误是发生在streamsocket上,因为streamsocket才会建立连接。
对于datagramsocket,多次成功的connect()函式呼叫是被允许的(对于datdgramsocket而言,呼叫connect()函式的目的不在于建立连接)。
datagramsocket发生此错误的原因是在sendto()函式上,当呼叫sendto()传送datagram时,如果对方位址填入INADDR_ANY(“0.0.0.0”)而port填入0(在sockaddr_in结构中),就会导致WSAEISCONN这个错误。
WSAENOTCONN(10057)socket尚未连接
网路函式通常会有一定的呼叫顺序,有些函式必须先呼叫成功某函式才能呼叫。
WSAENOTCONN这个错误发生的原因很明显,就是在连接建立之前,你试图从连接对方取得资料或是传送资料到对方,就会发生WSAENETCONN这个错误。
举例来说,对于streamsocket,如果在建立连结前呼叫send()试图传送资料,或者是呼叫recv()试图取得资料,就会发生这个错误,告诉你socket尚未建立连接。
你如果呼叫了getpeername()这个函式试图去取得连接对方的socket,当然也会出现这个错误。
对于setsockopt()这个函式,如果设定SO_KEEPALIVE,但连接已被中断的话,也会出现WSAENETCONN这个错误。
初学者可能在呼叫connect()函式之后没有检查是否函式呼叫错误,以致不知道是否连接已正确建立。
WSAESHUTDOWN(10058)socket已经关闭
这个错误码的意思是,无法再传送资料了,因为socket已经经由shutdown()函式而关闭了。
当你利用shutdown()关闭socket之后,WinSock的TCP/IP协定核心就会关闭这个socket的传送或接收的功能。
有一点要注意的是,这个错误只会在streamsocket出现。
WSAETOOMANYREFS(10059)参照(reference)太多,资源耗尽
在UNIX作业系统中的解释是指系统核心资源消耗殆尽。
不过在WinSock1.1版的规格书中并没有任何一个函式会发生这种错误。
WSAETIMEDOUT(10060)连接逾时(timeout)
当程式试图利用connect()连接一台远端主机时,此主机一直没有回应,经过了一段时间后,TCP/IP协定核心便会传回connect()函式WSAETIMEDOUT这个错误讯息。
发生这个错误的原因可能是程式所要连接的远端主机的系统发生问题,或者根本没有这一台主机。
也有一种可能的原因是本地机器的网路系统出现问题,导致本地主机无法正常与远端主机联系。
检查你的网路系统的设定,看看有什么不当的地方,如闸道器(gateway)的设定,主机名称表(hosts)内主机名称和网路位址的对照有错误等等。
WSAECONNREFUSED(10061)连接受拒
连接要求受到对方机器的回绝,无法和对方建立连接。
这个错误并不是网路系统出了问题,而是对方机器的server程式拒绝client程式的连接要求,或者是根本没有这个server程式存在。
当TCP/IP核心收到某个连接要求时,会查看系统中是否有某server程式所监听的port正好是这个连接要求所要连接的port,如果没有此server程式,TCP/IP核心会回绝一个WSAECONNREFUSED给对方程式。
通常发生这个错误的原因有几个。
使用者可能连接到错误的远端主机或是错误的port,也有可能是远端主机和port对了,但是server程式并没有执行。
检查看看程式中的sockaddr_in结构有没有填错?
sockaddr_in中的IP位址和port是不是以网路位元组顺序排列。
WSAELOOP(10062)太多层的符号式链结(Symboliclink)
在UNIX作业系统中,这个错误的意思是指路径参考过多的符号式链结(symboliclink)。
WSAENAMETOOLONG(10063)档名过长
在UNIX作业系统,这个错误的意思是指欲开启档案的路径名称(包括档案名称)太长。
WSAEHOSTDOWN(10064)对方主机关闭
在柏克莱socket介面的解释中,这个错误发生的原因是当远端主机关闭或系统出问题。
WS