附录A Windows Sockets错误码
Windows Sockets在头文件winsock.h中定义了所有的错误码,它们包括以“WSA”打头的Windows Sockets实现返回的错误码和Berkeley Sockets定义的错误码全集。定义Berkeley Sockets错误码是为了确保原有软件的可移植性。
A.1 Windows Sockets错误码列表
表A.1列出了WSAGetLastError()函数返回的可能错误码和它们的解释,它们可分为四个部分。
错误码的第一部分是用来解决在不同的C编译中对标准C错误码的不一致的定义。错误码的第二部分是标准Berkeley Sockets错误码的Windows Sockets版本。错误码的第三部分包括特定Windows Sockets扩充的错误码。错误码的第四部分由Windows Sockets的getXbyY()和WSAAsyncGetXByY()函数返回,相当于Berkeley软件中由变量h_errno返回的错误(事实上,Windows Sockets在头文件winsock.h中已将h_error定义成其值为WSAGetLastError()的一个宏),它们相当于由域名服务(Domain Name Service)返回的各种失败。如果Windows Sockets实现没有使用域名服务,它将使用最合适的代码。一般地,Windows Sockets应用程序应该将错误WSAHOST_NOT_FOUND和WSANO_DATA解释为指示关键字(名字,地址等)没有找着,而错误WSATRY_AGAIN和WSANO_RECOVERY是提醒名字服务自身是非操作的。
错误码由Windows Sockets 规范定义,在所有同一版本规范的Windows Sockets兼容实现中,它们是一致的。
表A.1 Windows Sockets错误码
Windows Sockets错误码 | Berkeley 对应错误码 | 错误号 | 解 释 |
WSAEINTR | EINTR | 10004 | 同标准C |
WSAEBADF | EBADF | 10009 | 同标准C |
WSAEACCES | EACCES | 10013 | 同标准C |
WSAEFAULT | EFAULT | 10014 | 同标准C |
WSAEINVAL | EINVAL | 10022 | 同标准C |
WSAEMFILE | EMFILE | 10024 | 同标准C |
WSAEWOULDBLOCK | EWOULDBLOCK | 10035 | 同BSD |
WSAEINPROGRESS | EINPROGRESS | 10036 | 当一个阻塞函数正在进行时,调用任何Windows Sockets API函数均返回此错误 |
WSAEALREADY | EALREADY | 10037 | 同BSD |
WSAENOTSOCK | ENOTSOCK | 10038 | 同BSD |
WSAEDESTADDRREQ | EDESTADDRREQ | 10039 | 同BSD |
WSAEMSGSIZE | EMSGSIZE | 10040 | 同BSD |
WSAEPROTOTYPE | EPROTOTYPE | 10041 | 同BSD |
WSAENOPROTOOPT | ENOPROTOOPT | 10042 | 同BSD |
WSAEPROTONOSUPPORT | EPROTONOSUPPORT | 10043 | 同BSD |
WSAESOCKTNOSUPPORT | ESOCKTNOSUPPORT | 10044 | 同BSD |
WSAEOPNOTSUPP | EOPNOTSUPP | 10045 | 同BSD |
WSAEPFNOSUPPORT | EPFNOSUPPORT | 10046 | 同BSD |
WSAEAFNOSUPPORT | EAFNOSUPPORT | 10047 | 同BSD |
WSAEADDRINUSE | EADDRINUSE | 10048 | 同BSD |
WSAEADDRNOTAVAIL | EADDRNOTAVAIL | 10049 | 同BSD |
WSAENETDOWN | ENETDOWN | 10050 | 同BSD。任何时候只要Windows Sockets实现检测到网络子系统失败,它就报告此错误。 |
WSAENETUNREACH | ENETUNREACH | 10051 | 同BSD |
WSAENETRESET | ENETRESET | 10052 | 同BSD |
WSAECONNABORTED | ECONNABORTED | 10053 | 同BSD |
WSAECONNRESET | ECONNRESET | 10054 | 同BSD |
WSAENOBUFS | ENOBUFS | 10055 | 同BSD |
WSAEISCONN | EISCONN | 10056 | 同BSD |
WSAENOTCONN | ENOTCONN | 10057 | 同BSD |
WSAESHUTDOWN | ESHUTDOWN | 10058 | 同BSD |
WSAETOOMANYREFS | ETOOMANYREFS | 10059 | 同BSD |
WSAETIMEDOUT | ETIMEDOUT | 10060 | 同BSD |
WSAECONNREFUSED | ECONNREFUSED | 10061 | 同BSD |
WSAELOOP | ELOOP | 10062 | 同BSD |
WSAENAMETOOLONG | ENAMETOOLONG | 10063 | 同BSD |
WSAEHOSTDOWN | EHOSTDOWN | 10064 | 同BSD |
WSAEHOSTUNREACH | EHOSTUNREACH | 10065 | 同BSD |
WSASYSNOTREADY |
| 10091 | 由WSAStartup() 返回,指示网络子系统无法使用。 |
WSAVERNOTSUPPORTED |
| 10092 | 由WSAStartup() 返回,指示Windows Sockets |
WSANOTINITIALISED |
| 10093 | 由除WSAStartup()之外的其它函数返回,指示 尚没有一次成功的WSAStartup() 调用执行过。 |
WSAEDISCON |
| 10101 | 由WSARecv()和WSARecvFrom()返回,指示远程方已经初始化了一个“雅致”的shutdown序列。 |
WSAHOST_NOT_FOUND | HOST_NOT_FOUND | 11001 | 同BSD |
WSATRY_AGAIN | TRY_AGAIN | 11002 | 同BSD |
WSANO_RECOVERY | NO_RECOVERY | 11003 | 同BSD |
WSANO_DATA | NO_DATA | 11004 | 同BSD |
A.2 Windows Sockets错误码扩展描述
下面给出WSAGetLastError()函数返回的可能错误码按字母顺序排列的列表,同时给出简要的扩展描述。
WSAEACCES (10013) Permission denied.
试图使用被禁止的访问权限去访问套接字。例如,在没有使用函数setsockopt()的SO_BROADCAST命令设置广播权限的套接字上使用函数sendto()给一个广播地址发送数据。
WSAEADDRINUSE (10048) Address already in use.
正常情况下每一个套接字地址(协议/IP地址/端口号)只允许使用一次。当应用程序试图使用bind()函数将一个被已存在的或没有完全关闭的或正在关闭的套接字使用了的IP地址/端口号绑扎到一个新套接字上时,该错误发生。对于服务器应用程序来说,如果需要使用bind()函数将多个套接字绑扎到同一个端口上,可以考虑使用setsockopt()函数的SO_REUSEADDR命令。客户应用程序一般不必使用bind()函数——connect()函数总是自动选择没有使用的端口号。当bind()函数操作的是通配地址(包括ADDR_ANY)时,错误WSAEADDRINUSE可能延迟到一个明确的地址被提交时才发生。这可能在后续的函数如connect()、listen()、WSAConnect()或WSAJoinLeaf()调用时发生。
WSAEADDRNOTAVAIL (10049) Cannot assign requested address.
被请求的地址在它的环境中是不合法的。通常地在bind()函数试图将一个本地机器不合法的地址绑扎到套接字时产生。它也可能在connect()、sendto()、WSAConnect()、WSAJoinLeaf()或WSASendTo()函数调用时因远程机器的远程地址或端口号非法(如0地址或0端口号)而产生。
WSAEAFNOSUPPORT (10047) Address family not supported by protocol family.
使用的地址与被请求的协议不兼容。所有的套接字在创建时都与一个地址族(如IP协议对应的AF_INET)和一个通用的协议类型(如SOCK_STREAM)联系起来。如果在socket()调用中明确地要求一个不正确的协议,或在调用sendto()等函数时使用了对套接字来说是错误的地址族的地址,该错误返回。
WSAEALREADY (10037) Operation already in progress.
当在非阻塞套接字上已经有一个操作正在进行时,又有一个操作试图在其上执行则产生此错误。如:在一个正在进行连接的非阻塞套接字上第二次调用connect()函数;或取消一个已经被取消或已完成的异步请求(WSAAsyncGetXbyY())。
WSAECONNABORTED (10053) Software caused connection abort.
一个已建立的连接被你的主机上的软件终止,可能是因为一次数据传输超时或是协议错误。
WSAECONNREFUSED (10061) Connection refused.
因为目标主机主动拒绝,连接不能建立。这通常是因为试图连接到一个远程主机上不活动的服务,如没有服务器应用程序处于执行状态。
WSAECONNRESET (10054) Connection reset by peer.
存在的连接被远程主机强制关闭。通常原因为:远程主机上对等方应用程序突然停止运行,或远程主机重新启动,或远程主机在远程方套接字上使用了“强制”关闭(参见setsockopt(SO_LINGER))。另外,在一个或多个操作正在进行时,如果连接因“keep-alive”活动检测到一个失败而中断,也可能导致此错误。此时,正在进行的操作以错误码WSAENETRESET失败返回,后续操作将失败返回错误码WSAECONNRESET。
WSAEDESTADDRREQ (10039) Destination address required.
在套接字上一个操作所必须的地址被遗漏。例如,如果sendto()函数被调用且远程地址为ADDR_ANY时,此错误被返回。
WSAEFAULT (10014) Bad address.
系统检测到调用试图使用的一个指针参数指向的是一个非法指针地址。如果应用程序传递一个非法的指针值,或缓冲区长度太小,此错误发生。例如,参数为结构sockaddr,但参数的长度小于sizeof(struct sockaddr)。
WSAEHOSTDOWN (10064) Host is down.
套接字操作因为目的主机关闭而失败返回。套接字操作遇到不活动主机。本地主机上的网络活动没有初始化。这些条件由错误码WSAETIMEDOUT指示似乎更合适。
WSAEHOSTUNREACH (10065) No route to host.
试图和一个不可达主机进行套接字操作。参见WSAENETUNREACH。
WSAEINPROGRESS (10036) Operation now in progress.
一个阻塞操作正在执行。Windows Sockets只允许一个任务(或线程)在同一时间可以有一个未完成的阻塞操作,如果此时调用了任何函数(不管此函数是否引用了该套接字或任何其它套接字),此函数将以错误码WSAEINPROGRESS返回。
WSAEINTR (10004) Interrupted function call.
阻塞操作被函数WSACancelBlockingCall ()调用所中断。
WSAEINVAL (10022) Invalid argument.
提供了非法参数(例如,在使用setsockopt()函数时指定了非法的level)。在一些实例中,它也可能与套接字的当前状态相关,例如,在套接字没有使用listen()使其处于监听时调用accept()函数。
WSAEISCONN (10056) Socket is already connected.
连接请求发生在已经连接的套接字上。一些实现对于在已连接SOCK_DGRAM套接字上使用sendto()函数的情况也返回此错误(对于SOCK_STREAM套接字,sendto()函数的to参数被忽略),尽管其它一些实现将此操作视为合法事件。
WSAEMFILE (10024) Too many open files.
打开了太多的套接字。不管是对整个系统还是每一进程或线程,Windows Sockets实现都可能有一个最大可用的套接字句柄数。
WSAEMSGSIZE (10040) Message too long.
在数据报套接字上发送的一个消息大于内部消息缓冲区或一些其它网络限制,或者是用来接受数据报的缓冲区小于数据报本身。
WSAENETDOWN (10050) Network is down.
套接字操作遇到一个不活动的网络。此错误可能指示网络系统(例如WinSock DLL运行的协议栈)、网络接口或本地网络本身发生了一个严重的失败。
WSAENETRESET (10052) Network dropped connection on reset.
在操作正在进行时连接因“keep-alive”检测到失败而中断。也可能由setsockopt()函数返回,如果试图使用它在一个已经失败的连接上设置SO_KEEPALIVE。