SOCKET错误码详解

WSAEINTR 10004

操作被终止。例如:recvfrom阻塞的时候,如果你在其他线程调用closesocket,recvfrom会返回10004 (Interrupted function call,阻塞状态被打断,由于closesocket),
如果你检测到了10004错误,这是可以考虑退出如果你没有退出,继续循环调用recvfrom会返回 10038 (Socket operation on nonsocket,无效的socket)。

WSAEACCES 10013

访问被拒绝,如端口不能被绑定。

WSAEINVAL 10022  
官方解释:
        The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.

大概意思:套接口未用bind()捆绑,未bind,就listen,。例子如下:
FD_ZERO(&fdread);
FD_SET(connectsock,&fdread);
tv.tv_sec = 1;//设置延迟为1秒
tv.tv_usec = 0;
while(1)
{
   int iselect = select(0,&fdread,NULL,NULL,&tv);
   ......
}
    第一次select检查的时候没有报错,而第二次检查的时候就报了10022错误,原因如下:
    select函数:如果程序要检查套接字上是否有数据到来,则首先需要把套接字句柄加入可读性监视集合中,然后调用select,如果该套接字没有数据需要接收,则select函数会把该套接字从可读性监视集合中删除,所以,程序只要检查该套接字句柄是否还在可读性监视集合中,就可以判断出是否有数据需要接收。因此我们第一次调用select函数的时候,没有数据到来,select函数将套接字从可读性监视集合中删除,而我们第二次调用select函数的时候,系统认为你提供了非法参数,所以会报10022错误。
    代码需改为如下:
while(1){
   FD_ZERO(&fdread);
   FD_SET(connectsock,&fdread);
   tv.tv_sec = 1;//设置延迟为1秒
   tv.tv_usec = 0;
   int iselect = select(0,&fdread,NULL,NULL,&tv);
......
}

WSAEWOULDBLOCK 10035

This error is returned from operations on nonblocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a nonfatal error, and the operation should be retried later. It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established

大概意思是:非阻塞SOCKET的操作不能立即执行,这不是个执行错误,稍后可以重试,比如对一个非阻塞的SOCKT执行 recv/recvfrom,如果收不到数据,就会返回-1,原因就是WSAEWOULDBLOCK

WSAEINPROGRESS 10036

当一个阻塞函数正在进行时,调用任何Windows Sockets API函数均返回此错误。

WSAENOTSOCK 10038

解释:An operation was attempted on something that is not a socket。

WSAEMSGSIZE 10040

sendto/recvfrom时有时候出现10040的错误,查MSDN知这个错误是发送/接收buffer不够大引起的。用setsockopt将socket的send/recv的buffer加大。

WSAECONNRESET  10054
官方解释:
        The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UPD-datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

问题分析:这个错误一般是使用UDP Socket接受时收到(这里我不讲具体的语言了,不管你用C#、Python还是C,在Windows下都会有类似的问题,只要你调用类似ReceiveFrom函数)。这是上一次Send操作向一个地址发送,但是那个地址没有Socket监听(例如对等体崩溃),那么ICMP控制协议会向我们发送一个Port Unreachable错误,当然这个错误应该包含对方的详细地址等信息,但是Winsock把这个错误转化为Connection Reset,在你下一次调用读操作的时候,引发异常,却没把详细信息给你——例如用C#接受到的对方地址是0.0.0.0。
例:对方SOCKET关闭,会收到此错误码。

#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)

 BOOL bNewBehavior = FALSE;
DWORD dwBytesReturned;

WSAIoctl(m_Sckt, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山西茄子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值