Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 非阻塞tun/tap文件描述符上的read()获取EAGAIN错误_Sockets_File Descriptor_Openvpn_Tun - Fatal编程技术网

Sockets 非阻塞tun/tap文件描述符上的read()获取EAGAIN错误

Sockets 非阻塞tun/tap文件描述符上的read()获取EAGAIN错误,sockets,file-descriptor,openvpn,tun,Sockets,File Descriptor,Openvpn,Tun,我想从非阻塞tun/tap文件描述符读取IP数据包tunfd 我将tunfd设置为非阻塞,并在libevent中为其注册一个READ_EV事件 当事件被触发时,我首先读取前20个字节以获取IP头,然后 读剩下的 nr_bytes = read(tunfd, buf, 20); ... ip_len = .... // here I get the IP length .... nr_bytes = read(tunfd, buf+20, ip_len-20); 但是对于读取(tunfd,buf

我想从非阻塞tun/tap文件描述符读取IP数据包
tunfd
我将
tunfd
设置为非阻塞,并在libevent中为其注册一个READ_EV事件

当事件被触发时,我首先读取前20个字节以获取IP头,然后 读剩下的

nr_bytes = read(tunfd, buf, 20);
...
ip_len = .... // here I get the IP length
....
nr_bytes = read(tunfd, buf+20, ip_len-20);
但是对于
读取(tunfd,buf+20,ip_len-20)
我犯了一个错误,实际上应该有一个完整的包, 所以应该有一些字节, 为什么我会犯这样的错误

tunfd与非阻塞模式或libevent不兼容


谢谢

使用TUN/TAP进行读写,就像在数据报套接字上进行读写一样,必须针对完整的数据包。如果读入的缓冲区太小,无法容纳完整的数据包,缓冲区将被填满,数据包的其余部分将被丢弃。对于写入,如果您写入部分数据包,驱动程序将认为它是完整的数据包,并通过隧道设备发送截断的数据包


因此,当您读取TUN/TAP设备时,必须提供至少与
TUN
TAP
界面上配置的MTU一样大的缓冲区。

您的意思是,每次read()只能返回正好1个数据包?不是多个包?此外,如果我太频繁地向tun fd写入数据,并且没有足够的缓冲区,会发生什么?例如,如果只有200字节的缓冲区,但我想写一个500字节的数据包。将写入200个字节还是500个字节都不写入?谢谢是,
read()
一次只能返回1个(完整)数据包。如果
write()
太多,那么
write()
可能最终会被阻止,但它仍然只会写入完整的数据包。write()会被阻止吗?如果套接字是非阻塞的,它不是返回一个EAGAIN错误吗?哦,是的,当然。如果您处于非阻塞模式,它将返回
EAGAIN
,而不是阻塞。这是正确的,@SimonLanghoff。使用缓冲读写器的原因之一是批量处理更多数据并减少
read()
/
write()
/
recv()
/
send()
系统调用的数量。但对于TUN/TAP,一个系统调用=一个数据包是接口的要求,因此您无法进行优化。