2015-12-12 48 views
0

我有一个关于TCP连接中的非阻塞套接字的问题。将TCP客户端套接字设置为非阻塞:服务器vs客户端

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

我的服务器异步运行和我的客户在一个固定的速度运行。因此,我想要有一个无阻塞的套接字来将数据从客户端发送到服务器s.t.客户端可以以固定速率发送数据而不会停止,并且服务器会同时读取所有已缓冲的数据。

所以我的问题是:如果我在客户端或服务器类中将客户端套接字设置为非阻塞,是否有所作为?(使用fcntl(this->newsockfd_, F_SETFL, fcntl(this->newsockfd_, F_GETFL, 0) | O_NONBLOCK),其中this->newsockfd_是这两类客户的套接字文件描述符)

我在PROGRAMM尝试这样做,它似乎像客户端套接字设置为非阻塞的客户端类没有做的伎俩,但将其设置在服务器级别上。但是,我不明白为什么这应该有所作为。

+1

在什么区别?将套接字设置为非阻塞意味着套接字读取,写入和其他套接字操作将立即返回。然后,您必须准备好处理没有数据传输的情况,因为操作通常会因为没有可读取的数据或出站网络缓冲区已满而被阻塞等。 –

回答

-1

由于您的客户端只发送数据,非阻塞设置不会影响它。根据套接字编程上出色的beej.us guide,只有对accept()recv()的调用受到非阻塞设置的影响。由于只有您的服务器正在调用这些服务器代码,因此您会看到服务器代码发生更改如果你的客户端收到数据,那么非阻塞设置会影响它,你将不得不使用select()来检查是否有数据并相应地读取数据。

+0

此答案错误,因为发送可以阻止以及。 beej说很多功能块。接受()块。所有recv()函数都会阻塞。 accept和recv函数不是很多,只有2个可以阻止的函数的例子。如上所述,发送也可以阻止。 –

+0

您的引用没有说明您声称的内容,而第三方网站不是规范性参考。你应该引用* man *页面或Posix,它们也不这样说。 – EJP

1

如果你的套接字被设置为非阻塞模式,你将会得到。它永远不会阻止。但这并不意味着你的api电话会成功。

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

你尽管服务器率以均匀的速率发送接收的想法,是不可能的。您不能让客户端以固定的速率发送。 TCP的整体思想是在客户端和服务器之间进行不断的协商,速度将取决于网络条件。拥塞等等。

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

有客户端和与阻塞和非阻塞套接字工作之间的服务器上有很大的区别的。在我看来,非阻塞套接字更难以处理。您需要选择api,并且超时很可能会检测到所有可能的套接字状态。在阻塞套接字的情况下,你可以在一个线程中使用一个套接字,如果套接字阻塞,它就是阻塞的线程。如果你的GUI是在不同的线程上,GUI将会响应。