http://blog.sina.com.cn/s/blog_6ffee9410100pqdt.html

折腾了一个下午加大半个晚上,查了300多个网页,20多个技术论坛,终于把这个问题解决了,真不容易。总结下出现这个错误的一般原因和我出错的原因。

出现这个错误的一般原因:

1.fromlen参数没有初始化

2.from参数没有设置正确,也就是结构问题

3.参数作用域问题

我出错的原因:

在查找过程中,曾发现部分帖子上说过bind()的问题,但自恃对UDP通信了如指掌,入行以来所做的UDP客户端为了不跟其他程序抢端口,提高程序的通用性,从来不绑定也没出过错,不屑地认为他们在胡说八道,纯粹外行人的说法。不想这回还真栽这上边了。

这个系统我采用了一个套接字4线程通用的方法,在主线程中初始化,在接收线程、网络预处理线程、处理线程、发送线程中共用。考虑到各个线程的同步和信息同步的问题,首先启动的是接收线程。于是问题出来了,recvfrom函数一直在报错10022,look error说是参数错误。在网上查了大半天,几乎所有参数都进行了改动尝试,断点取值查看,结果参数一点问题都没有,甚至将以前的程序拷贝过来测试也没用,十分郁闷,都准备晚上不睡觉奋战到底了。

百度google的网页都快翻遍的时候实在受不了了,摔了鼠标去冲咖啡。闻到咖啡浓香的时候突然想到一个问题:socket之所以不绑定,是系统会自动分配端口,这只是对发送函数来讲的,如果不绑定而直接调用接收函数,如果我是写这个函数的人,我会怎么办?我知道该从哪个端口接收吗?不知道。如果我随便找个端口,有一种情况会根本没法处理,就是只接收数据而不往外部发送数据的时候,整个系统,包括外部要通信的系统都不会知道我在这个端口接收数据,那这个接收函数就变得毫无意义。我当然不会白痴到留下这么个漏洞,那个比我高N级的编写这个的软件工程师更加不会。所以,要报错。所以就有了10022。

当然,这只是假想,只是猜测,要经实际验证的。我绑定个端口后发现竟然通了,假想得到验证。

另外一种猜想:如果不绑定端口,而在接收之前进行一次发送,依照我的上一个猜想,依然可以行得通。因为在发送的时候系统自动分配了端口,这样除了发送函数知道那个端口外,系统其他部分也知道了。当然,这只是猜想的猜想,还需要验证。不过今天晚上太晚了,还有点东西没调完,明天再验证吧。

花了这么多时间,查了这么多资料,发现我犯的错误竟然是前无古人,后难有来者,所有的资料中都没有记载或者没有解释。当真值得记上一笔。

以后多想想编这个系统的人是怎么想的,或许能省点时间,毕竟他们也是人,再高级的工程师也是写程序的,跟我本质上没什么区别,区别就在于他们都比我年纪大。

记录一个使用socket库中遇到的问题,最近项目中遇到使用本地udp通信的情况,在编写程序过程中,发现调用 recv from一直失败,返回-1,错误码 10022 (错误码很重要)。排查了半个下午,终于发现原来是bind函数的问题。由于在文件开头使用了 using namespace std 导致默认的bind变成了 functional中的那个,而不是socket的bind,导致绑定一直没有成功。当然,也可能是套接字端口被占用, recv from直接返回-1(但运行不报错),错误码是10044和 10022 (放在不 在 TCP 中,套接字之间应该是一对一的关系。若向 10 个客户端提供服务,则除了守门的服务器套接字外,还需要 10 个服务器端套接字。但在 UDP 中,不管是服务器端还是客户端都。 2.经过多次试验,排查到原因,是因为客户端使用大小为32的缓冲区char recv Buffer[32]进行接收,但主控发送时,发送的大小为sizeof(CLIENTDATA) = 65,导致客户端接收失败,返回-1,即使客户端套接字状态正常依然返回-1。当客户端接收缓冲区改为大于主控发送的数据的任意大小缓冲区, recv from不再返回-1。3.所以,使用UDP进行数据传输时,接收端 recv from时缓冲区的大小要大于发送端发送数据的大小,否则 recv from返回SOCKET_ ERROR ,即-1。 路径:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Winsock。按下windows键+R键,输入regedit,打开注册表,在文件目录里找到如下两个文件夹,删除这两个文件夹。这2个注册表选项千万不能删除,否则上不了网。只能从其他电脑上复制过来。 【提供可能的解决思路】本地编写UDP通信, recv from不阻塞,并一直返回-1 记录一个使用socket库中遇到的问题,最近项目中遇到使用本地udp通信的情况,在编写程序过程中,发现调用 recv from一直失败,返回-1,错误码 10022 。 排查了半个下午,终于发现原来是bind函数的问题。 由于在文件开头使用了 using namespace std 导致默认的bind变成了 functional.h中的那个,而不是socket的bind,导致绑定一直没有成功。 解决方案: 1.不要在文件中用 usi windows socket编程中调用 recv from返回-1(windows error 10014)错误的问题标签(空格分隔): socket在windows平台下进行socket编程时,调用 recv from函数,始终返回-1,然后根据WSAGetLast Error ()获取到错误码为10014,查了网上说的几乎所有方法,全部没有一点问题,代码如下: struct sockaddr_in r <br />WinSock Recv from() 现在返回 WSAECONNRESET 代替阻止或超时如果为 readfds 设置了一个使用中的"无法到达 ICMP 端口"响应和 select 函数 sendto 函数结果的数据报发送该程序就会返回 1 和后续调用 recv from 函数使用 WSAECONNRESET (10054) 错误响应无法正常工作。在 Microsoft Windows NT 4.0,这种情况下将导致 select 函数块或超时时间。<br />下面的代码段演示一种技术