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

时间:2015-12-12 12:16:48

标签: c++ sockets tcp

我对TCP连接中的非阻塞套接字有疑问。

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

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

所以我的问题是:如果我在客户端或服务器类中将客户端套接字设置为非阻塞,会不会产生影响?(使用fcntl(this->newsockfd_, F_SETFL, fcntl(this->newsockfd_, F_GETFL, 0) | O_NONBLOCK),其中{{ 1}}是两个类中客户端的套接字文件描述符)

我在我的程序中尝试了这个,似乎在客户端类中将客户端套接字设置为非阻塞没有做到这一点,但是在服务器类中进行设置确实如此。但是,我不明白为什么这会产生影响。

2 个答案:

答案 0 :(得分:1)

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

在幕后使用缓冲区,如果它们已满,这意味着在套接字阻塞的阻塞模式下,您将收到返回代码EWOULDBLOCK,这意味着您的发送失败。这意味着您基本上必须等待缓冲区清空,然后再试一次。

无论服务器速率是否接收,您想以均匀的速率发送都是不可能的。您无法让客户以固定费率发送邮件。 TCP的整个想法是客户端和服务器之间存在持续协商,速度将在很大程度上取决于网络条件。拥挤等。

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

在使用阻塞和非阻塞套接字之间,客户端和服务器上存在很多差异。在我看来,非阻塞插座更难以处理。您需要选择api,超时很可能检测到所有可能的套接字状态。在阻塞套接字的情况下,你可以在一个线程中使用套接字,如果套接字阻塞,它也只是阻塞的线程。如果您的gui位于不同的线程上,GUI将会响应。

答案 1 :(得分:-1)

由于您的客户端仅发送数据,因此非阻止设置不会影响它。根据套接字编程的优秀beej.us guide,只有accept()recv()的调用受非阻塞设置的影响。由于只有您的服务器正在调用这些服务器,您才会看到服务器代码的更改。如果您的客户端收到数据,那么非阻止设置会影响它,您必须使用select()来检查是否有数据并从中进行相应的读取。