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
C++ 将TCP客户端套接字设置为非阻塞:服务器与客户端_C++_Sockets_Tcp - Fatal编程技术网

C++ 将TCP客户端套接字设置为非阻塞:服务器与客户端

C++ 将TCP客户端套接字设置为非阻塞:服务器与客户端,c++,sockets,tcp,C++,Sockets,Tcp,我有一个关于TCP连接中的非阻塞套接字的问题 我已经实现了两个C++类,一个用于TCP服务器,一个用于客户端。服务器有两个套接字文件描述符,一个用于服务器,一个用于客户端。客户端有一个套接字文件描述符 我的服务器异步运行,我的客户端以固定速率运行。因此,我希望有一个非阻塞套接字,用于将数据从客户机发送到服务器s.t。客户机可以以固定速率发送数据,而无需暂停,服务器同时异步读取所有已缓冲的数据 因此,我的问题是:如果我在客户机或服务器类中将客户机套接字设置为非阻塞,这会有区别吗?(使用fcntl(

我有一个关于TCP连接中的非阻塞套接字的问题

我已经实现了两个C++类,一个用于TCP服务器,一个用于客户端。服务器有两个套接字文件描述符,一个用于服务器,一个用于客户端。客户端有一个套接字文件描述符

我的服务器异步运行,我的客户端以固定速率运行。因此,我希望有一个非阻塞套接字,用于将数据从客户机发送到服务器s.t。客户机可以以固定速率发送数据,而无需暂停,服务器同时异步读取所有已缓冲的数据

因此,我的问题是:如果我在客户机或服务器类中将客户机套接字设置为非阻塞,这会有区别吗?(使用
fcntl(this->newsockfd,F_SETFL,fcntl(this->newsockfd,F_GETFL,0)| O_NONBLOCK)
,其中
this->newsockfd
是这两个类中的客户机套接字文件描述符)


我在我的程序中尝试了这一点,似乎在客户机类中将客户机套接字设置为非阻塞并没有起到作用,但在服务器类中设置了它。但是,我不明白为什么这会产生不同。

因为您的客户端只发送数据,所以非阻塞设置不会影响它。根据出色的on-socket编程,非阻塞设置只影响对
accept()
recv()
的调用。因为只有您的服务器在调用这些代码,所以您可以看到服务器代码的变化。如果您的客户端接收到数据,则非阻塞设置将影响数据,您必须使用
select()
检查是否有数据,并相应地从中读取数据。

如果您的套接字设置为非阻塞模式,您将只获得该数据。它永远不会阻塞。但这并不意味着您的api调用会成功

有一些缓冲区正在后台使用,如果它们已满,这意味着在阻塞模式下套接字将被阻塞,您将得到一个返回码ewoldblock,这意味着您的发送失败。这意味着您基本上必须等待缓冲区清空,然后重试

不管服务器的接收速率如何,您都不可能以平均速率发送。您不能让客户端以固定速率发送。TCP的整体思想是,客户端和服务器之间有一个持续的协商,其速度在很大程度上取决于网络条件。交通堵塞等等

移动到非阻塞套接字本身会产生一些问题。您必须检测发送失败,必须检查套接字是否再次可写,必须存储尝试发送的字节,并在套接字再次可写时重新尝试发送


使用阻塞套接字和非阻塞套接字在客户端和服务器上都有很大的区别。在我看来,非阻塞套接字更难处理。您需要select api,超时很可能会检测到所有可能的套接字状态。在阻塞套接字的情况下,您可以在线程中使用套接字,如果套接字阻塞,那么也只有线程会阻塞。如果您的gui位于不同的线程上,gui将响应。

在什么方面存在差异?将套接字设置为非阻塞意味着套接字读取、写入和其他套接字操作将立即返回。然后,您必须准备好处理没有传输数据的情况,因为操作通常会因为没有可读取的数据而被阻止,或者出站网络缓冲区已满等。这个答案是错误的,因为发送也会被阻止。beej说很多函数都会阻塞。accept()块。所有recv()函数都被阻塞。accept和recv不是很多函数,只是两个可以阻塞的函数示例。如前所述,“发送”也可以阻止。你的引用并没有说明你的主张,第三方网站也不是一个规范性参考。您应该引用手册页或Posix,它们也没有这样说。