首页
博客
研修院
VIP
APP
问答
下载
社区
推荐频道
活动
招聘
专题
打开CSDN APP
Copyright © 1999-2020, CSDN.NET, All Rights Reserved
打开APP
Hilaph
关注
Windows UDP recvfrom 不能阻塞 及 bind 报错的解决办法 原创
2020-07-09 18:44:15
Hilaph
码龄6年
关注
1、正常来说,UDP的recvfrom默认是阻塞的。
可以手动设置是否为阻塞
u_long iMODE = 0//1为非阻塞,0为阻塞
ioctlsocket(udp_cliSocket, FIONBIO, &iMODE)//设置recvfrom是否为阻塞
ioctlsocket的第一个参数为socket套接字。
此处我设置为0,依然会不阻塞。
2、如果bind失败了,也会导致recvfrom不阻塞。
if (bind(udp_cliSocket, (SOCKADDR*)&locAddr, sizeof(locAddr)) == SOCKET_ERROR)
{
printf("UDP bind ERROR :%d\n", WSAGetLastError())
}
如果bind=SOCKET_ERROR时,说明bind失败,通过WSAGetLastError获取报错信息为10049——不能分配请求的地址。
再次检查前面的代码,发现添加本地ip时给错了地址。。。
文章知识点与官方知识档案匹配
网络技能树首页概览
21461 人正在系统学习中
打开CSDN,阅读体验更佳
UDP服务recvfrom函数设置非阻塞_leon_zeng0的博客_recvfrom...
所以,接收情况的判断需要利用recvfrom 的返回值。 新的补充: 不用上面那样复杂,也可以直接用不阻塞标志,如下: ret=recvfrom(sockfd,recvbuff,recvbufflen,MSG_DONTWAIT,( struct sockaddr *) &cliaddr, &clientlen)就是flags标志...
继续访问
recvfrom函数 非阻塞_IO - 同步、异步、阻塞、非阻塞
2 同步非阻塞IO process在NonBlocking IO读recvfrom *** 作的第一个阶段是不会block等待的,如果kernel数据还没准备好,那么recvfrom会立刻返回一个EWOULDBLOCK错误。当kernel准备好数据后,进入处理的第二阶段的时候,process会等待kernel将数据copy...
继续访问
最新发布 UDP socket 设置为的非阻塞模式
非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写 *** 作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write 到一部分的情况.对于一个TCP套接口,内核将从应用进程的缓冲区到该套接口的发送缓冲区拷贝数据。
继续访问
【网络协议】转载:关于TCP与UDP的接收recv和recvfrom
关于TCP与UDP的接收recv和recvfrom 技术标签: 网络协议 计算机网络 1.UDP发包的问题 问:udp 发送(sendto)两次数据,第一次 100字节 ,第二次200字节, 接包方一次recvfrom( 1000 ), 收到是 100,还是200,还是300? 答:UDP是数据报文协议,是以数据包方式,所以每次可以接收100,200,在理想情况下,第一次是无论recvfrom多少都是接收到100。当然,可能由于网络原因,第二个包先到的话,有可能是200了。对可能会由于网络原因乱序,所
继续访问
【提供可能的解决思路】本地编写UDP通信,recvfrom不阻塞,并一直返回-1
【提供可能的解决思路】本地编写UDP通信,recvfrom不阻塞,并一直返回-1 记录一个使用socket库中遇到的问题,最近项目中遇到使用本地udp通信的情况,在编写程序过程中,发现调用recvfrom一直失败,返回-1,错误码10022。 排查了半个下午,终于发现原来是bind函数的问题。 由于在文件开头使用了 using namespace std 导致默认的bind变成了 functional.h中的那个,而不是socket的bind,导致绑定一直没有成功。 解决方案: 1.不要在文件中用 usi
继续访问
socket学习:windows平台用udp模式接收数据,recvfrom函数返回值为-1,但是接收缓冲区中中却有数据
现象:windows平台用udp模式接收数据,recvfrom函数返回值为-1,但是接收缓冲区中中却有数据 方法:用GetLastError(),errno为10040, 错误含义: 一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小 最后发现原因:接收缓冲buf设置较小,发送方发送的数据超出了接收位置的长度 ...
继续访问
热门推荐 UDP服务recvfrom函数设置非阻塞
基本概念: 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 方法一源码,编译:g++ udp_server.cpp -o server #include #include #include #include #include #include #include #include #include #i
继续访问
关于send和recv在UDP的使用
在socket编程中,包括有连接和无连接两种方式,其流程如下: 有连接: TCP客户端的流程一般是 socket-【bind】-connect-send/recv 无连接: UDP客户端的流程一般是 socket-【bind】-sendto/recvfrom send与sento相比,没有提供对方的地址,在有连接模式中, 连接已经事先建立好,当然不需要每次都提供对方地址。但是,即使在无连接模式中,...
继续访问
C++ UDP通信,recvfrom函数一直堵塞
对于UDP通信中,recvfrom函数一直阻塞的问题,首先要检查发送端……
继续访问
recvfrom不阻塞_一文带你区分阻塞、非阻塞、同步、异步IO
前言:在之前的Redis面试套路拆解的文章[Redis面试套路拆解(一)]中有提到过IO模型,并且IO模型本身也是一个比较容易混淆的高频面试考点,小黑板将在本篇文章帮你理清思路,区分各种IO模型~其实网络上已经有很多博客讲了这个问题,但是总是觉得看完之后还是迷迷糊糊的,感觉大家有点太执着于把这个问题讲的通俗易懂了,经常会举各种各样的例子,比如烧水、去银行办理业务之类的,然而看完之后反倒会产生更多的...
继续访问
SOCKET编程UDP,bind失败
佛了竟然是因为端口号 一直bind失败,找不到原因,没想到端口号的问题,可能是因为端口号已绑定,换个端口号; ret = bind(sServer, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr))std::cout <<retif ( ret== SOCKET_ERROR) { printf("BIND失败!\n")return} ...
继续访问
linux select read阻塞_阻塞&非阻塞&同步&异步之间的关系
一:阻塞与非阻塞阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。1.blockingIO(阻塞):1.1:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后...
继续访问
TCP、UDP 通信常用函数send,sendto,recv,recvfrom详解
send函数 int send( SOCKET s,const char FAR *buf,int len,int flags ) 不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。 客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。 该函数的第一个参数指定发送端套接字描述符; 第二个参数指...
继续访问
非阻塞recvfrom的设置
我想用UDP阻塞模式给硬件设备发包,然后收包。因为网络的问题,经常丢包,也就是发了之后没有响应。这样的话,recvfrom会一直停在那里,死机了一样。 能不能设成超时自动返回,或者其它什么解决办法,谢谢!我不想用非阻塞模式,据说比较耗资源。 //连接超时 //----------------
继续访问
udp_recv(UDP服务器端)
#include <stdio.h>#include <string.h>#include <strings.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#define BUFSIZE 64 #define PORT 8888 #define IP “0.0.0.0” int ma
继续访问
linux socket read 阻塞
read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。 怎么样以非阻塞的方式从管道中读取数据?因为我用read函数时,如果管道没有数据就会阻塞住
继续访问
如何将UDP的recvfrom函数设置为非阻塞或阻塞超时
本文先介绍我查看了的2篇文章,然后介绍linux 和windows 下的非阻塞设置。最后是非阻塞情况下接收情况的判断。 2篇博文 其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 https://blog.csdn.net/daiyudong202...
继续访问
网络编程原理与UDP实现
如何发送数据包? Q:当应用程序产生数据的时候,需要去构造数据包并发送到网络上去,但是由谁负责处理呢? A:现代 *** 作系统负责数据包得构造与发送,应用程序只需提供数据。 当应用程序产生数据时,应用程序将数据交给OS内核,然后在OS内核添加各层的首部,构建好数据包,然后交给网卡,发送到网络中去。 Q:应用程序如何向OS 发送数据呢? A: OS为程序提供了一个接口,即socket API,类似于系统调用函数。 Q:通过socket API,只需要提供数据吗? A:并不,还需要告诉OS 内核,目的端口是什么
继续访问
从另一个线程将recvfrom从阻塞状态唤醒
UDP的多线程程序,一般开一个线程循环调用recvfrom接收消息,当程序中止的时候,如果这个线程阻塞在recvfrom调用,并且没有消息到达,则这个线程无法终止,造成资源泄露等问题。 这里终止这个线程有六种方法: 1. 释放监听的fd,这个是最简单的方法,但是有一点要注意,就是close(fd)系统调用无效,必须要使用shutdown(fd, SHUT_RDWR)来将recvfrom唤醒,因
继续访问
Udp端口绑定失败
前段时间部署业务系统时候,需要用到udp广播的组件都无法启动,报错RuntimeError:bind fail in line of file ../../source/udpnetwork/UdpClient.cpp 段错误 吐核。排查配置文件搞了挺久,最后发现udp广播用的网段,PREFIX不是24,导致广播段不是默认的XX.XX.XX.255。配置文件默认是255,后面改了广播端地址后,绑定就正常了。 ...
继续访问
recvfrom不阻塞
经验分享
写评论
评论
4
点赞
踩
分享
打开CSDN APP阅读体验更佳
非阻塞socket设置方法:
fcntl(socket_fd, F_SETFL, fcntl (socket_fd, F_GETFL,0) | O_NONBLOCK)
非阻塞模式下错误处理:
EAGAIN和EWOULDBLOCK(windows下)错误,这表明你在非阻塞模式下调用了阻塞 *** 作,在该 *** 作没有完成就返回这个错误,关于此错误一种说法是此错误表示目前无端口可用,另一种说法说的是发送缓冲区已满,遇到这两种错误不能当作错误处理,一种处理方法是采用延时处理稍后发送/接收,另一种是在类似poll/select/epoll中继续监听下次继续发送/接收,很显然第一种方法不可取,影响性能。当发送大量数据时,可以通过缓存保存数据。如果出现EINTR错误,错误描述为Interrupted system call, *** 作也应该继续。如果recv的返回值为0,那表明连接已经断开,我们的接收 *** 作也应该结束。
发送数据:
阻塞与非阻塞send返回值没有区分,
<0,出错,
=0,连接关闭,
>0,发送数据大小。
非阻塞模式下返回值 <0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的, 继续发送。
阻塞模式下send会阻塞着发送数据,非阻塞模式下如果暂时无法发送数据会返回,不会阻塞着 send,因此需要循环发送。
接收数据:
阻塞与非阻塞recv返回值没有区分,
<0,出错,
=0,连接关闭,
>0,接收到数据大小,
非阻塞模式下返回 值 <0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况 下认为连接是正常的,继续接收。
阻塞模式下recv会阻塞着接收数据,非阻塞模式下如果没有数据会返回,不会阻塞着读,因此需要 循环读取。
连接:
TCP socket 被设为非阻塞后调用 connect ,connect 函数如果没有马上成功,会立即返回EINPROCESS(如果被中断返回EINTR) ,但 TCP 的 3 次握手还在继续进行。之后可以用 select /epoll检查连接是否建立成功(但不能再次调用connect,这样会返回错误EADDRINUSE)。
非阻塞 connect 有3 种用途:
(1). 在3 次握手的同时做一些其他的处理。
(2). 可以同时建立多个连接。
(3). 在利用 select/epoll 等待的时候,可以给 select/epoll 设定一个时间,从而可以缩短 connect 的超时时间。
使用非阻塞 connect 需要注意的问题是:
(1). 很可能 调用 connect 时会立即建立连接(比如,客户端和服务端在同一台机子上),必须处理这种情况。
(2). Posix 定义了两条与 select/epoll 和 非阻塞 connect 相关的规定:
连接成功建立时,socket 描述字变为可写。(连接建立时,写缓冲区空闲,所以可写)
连接建立失败时,socket 描述字既可读又可写。 (由于有未决的错误,从而可读又可写)
另外对于无连接的socket类型(SOCK_DGRAM),客户端也可以调用connect进行连接,此连接实际上并不建立类似SOCK_STREAM的连接,而仅仅是在本地保存了对端的地址,这样后续的读写 *** 作可以默认以连接的对端为 *** 作对象。
IP_HDRINCL选项需要administrator权限,或者修改注册表:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameter\DisableRawSecurity(类型为DWORD),把值修改为 1。如果没有,就添加DisableRawSecurity并将其值设置为1.欢迎分享,转载请注明来源:内存溢出
评论列表(0条)