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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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
C++ poll()系统调用的行为以及之后接收或发送数据的行为 让我们考虑下面的代码 pollfd file_descriptors[1]; file_descriptors[0].fd = sock_fd; file_descriptors[0].events = POLLIN; int return_value = poll(file_descriptors, 1, 0); if (return_value == -1) { cerr << strerror(errno); } else if (return_value == 0) { cerr << "No data available to be read"; } else { if (file_descriptors[0].revents & POLLIN) { recv(sock_fd, buff, 1024, 0); } } pollfd文件_描述符[1]; 文件描述符[0]。fd=sock\u fd; 文件描述符[0]。事件=POLLIN; int return\u value=poll(文件描述符,1,0); 如果(返回值==-1){cerr_C++_Sockets_C++11_Networking_Tcp - Fatal编程技术网

C++ poll()系统调用的行为以及之后接收或发送数据的行为 让我们考虑下面的代码 pollfd file_descriptors[1]; file_descriptors[0].fd = sock_fd; file_descriptors[0].events = POLLIN; int return_value = poll(file_descriptors, 1, 0); if (return_value == -1) { cerr << strerror(errno); } else if (return_value == 0) { cerr << "No data available to be read"; } else { if (file_descriptors[0].revents & POLLIN) { recv(sock_fd, buff, 1024, 0); } } pollfd文件_描述符[1]; 文件描述符[0]。fd=sock\u fd; 文件描述符[0]。事件=POLLIN; int return\u value=poll(文件描述符,1,0); 如果(返回值==-1){cerr

C++ poll()系统调用的行为以及之后接收或发送数据的行为 让我们考虑下面的代码 pollfd file_descriptors[1]; file_descriptors[0].fd = sock_fd; file_descriptors[0].events = POLLIN; int return_value = poll(file_descriptors, 1, 0); if (return_value == -1) { cerr << strerror(errno); } else if (return_value == 0) { cerr << "No data available to be read"; } else { if (file_descriptors[0].revents & POLLIN) { recv(sock_fd, buff, 1024, 0); } } pollfd文件_描述符[1]; 文件描述符[0]。fd=sock\u fd; 文件描述符[0]。事件=POLLIN; int return\u value=poll(文件描述符,1,0); 如果(返回值==-1){cerr,c++,sockets,c++11,networking,tcp,C++,Sockets,C++11,Networking,Tcp,如果调用poll()既不返回-1也不返回0,并且在位图revents中为文件\u描述符数组中的第一个条目设置POLLIN标志,那么调用recv()是否会阻塞 它不应该这样做,除非另一个线程已经从套接字读取了当前可用的所有数据 如果没有,那么数据是否会立即读取 对 假设调用poll()的方式与上面提到的方式相同。将读入多少数据 与已经到达的数据一样多 它是否将与对recv()的常规调用相同?即,在上述情况下,(程序员)的任意数量小于或等于1024 对 然后,如果我想在再次读取之前poll(),我是

如果调用
poll()
既不返回-1也不返回0,并且在位图revents中为
文件\u描述符
数组中的第一个条目设置
POLLIN
标志,那么调用
recv()
是否会阻塞

它不应该这样做,除非另一个线程已经从套接字读取了当前可用的所有数据

如果没有,那么数据是否会立即读取

假设调用
poll()
的方式与上面提到的方式相同。将读入多少数据

与已经到达的数据一样多

它是否将与对
recv()
的常规调用相同?即,在上述情况下,(程序员)的任意数量小于或等于1024

然后,如果我想在再次读取之前
poll()
,我是否只需从第一次调用
poll()
开始重复,直到所有数据都已完全读入(即,在客户机-服务器场景中,这将对应于正在完成的请求)

是。

如果返回严格的正值,则表示至少有一个描述符有一些数据要返回

因此,不应该被阻塞:因为有数据,它应该返回一些东西。在任何情况下,都不能保证调用会返回所有1024字节

因此,您必须检查
recv()
返回的字节数。最终,您必须循环轮询/接收,直到获得所有预期数据

您可以通过使用标志参数
MSG_DONTWAIT
调用,或者以更持久的方式通过
fcntl()
来控制阻塞/非阻塞行为

<强>编辑:请注意,如果套接字中出现了错误,可能会丢失投票所提供的可用数据,并阻止“代码”> ReCVE()/代码>违背所有期望。因此,显式地使用非阻塞标志是安全的(请考虑<代码> ReV()。可能返回错误代码,而不是读取的字节数)

如果对poll()的调用既不返回-1也不返回0,并且在位图revents中为文件描述符数组中的第一个条目设置POLLIN标志,那么对recv()的调用是否会阻塞?如果否,那么数据是否会立即读入

调用
poll
对调用
recv
没有影响。
recv
是否阻塞取决于调用
recv
时可用的数据以及套接字处于阻塞模式还是非阻塞模式

假设对poll()的调用与上面提到的方式相同。将读入多少数据?它是否与对recv()的常规调用相同?即,在上述情况下,(对程序员)任意数量小于或等于1024。那么如果我想要poll()在再次读取之前,我是否从第一次调用poll()开始重复,直到完全读入所有数据(即,在客户机-服务器场景中,这将对应于正在完成的请求)

假设您不想阻塞,您应该将套接字设置为非阻塞。您有两个基本选择。您可以调用receive函数一次,然后再调用
poll
。或者您可以继续调用receive,直到得到“Wild block”指示。如果套接字是TCP连接,则可以继续调用receive函数,直到收到“将阻塞”指示或接收的字节数少于要求的字节数

有三种常见的非阻塞I/O策略,您可以基于
poll
select
。所有这些策略都要求将套接字设置为非阻塞

1) 在执行I/O操作之前,您始终可以调用
poll
select
。然后,只有在
poll
select
获得读或写命中时,您才尝试执行单个读或写操作

2) 您可以先尝试
读取
写入
操作。如果立即成功,那就太好了。如果不成功,请等待
轮询
选择
点击,然后重试该操作

3) 在执行I/O操作之前,您可以调用
poll
select
。然后尝试多个
读取
s或
写入
s,直到您完成所有需要执行的操作或得到“将阻塞”指示。当您得到“将阻塞”指示时指示,您等待
select
poll
通知您,然后再尝试在该套接字上沿该方向执行另一操作

方法3可能是最常见的读取方法,方法2可能是最常见的写入方法


请务必记住,
poll
是一种状态报告功能,它告诉您当前信息。它不会提供任何未来的保证。假设来自
poll
的读取指示意味着未来的读取操作不会被阻止,这是一个错误,它已导致严重的错误,并导致严重的错误过去的安全含义。确保套接字操作不会阻塞的唯一方法是将套接字设置为非阻塞。

对于3,请参阅。基本上,如果一个套接字端发送正常数据,然后发送OOB数据,则客户端将尽快获取OOB数据,可能在另一个数据之前。[好吧,这取决于客户如何调用recv,以及其他一些事情,这还不是全部……请参阅链接]非常感谢!我将从该问题的答案中了解:)@deviantfan。我将忽略当前用例中的所有OOB数据。不过我还有一个后续问题。如果确实有一些OOB数据已被删除