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数据已被删除