阻塞套接字

时间:2015-06-27 22:37:22

标签: c multithreading sockets

我正在编写一个小型的c linux本地服务器。我已经阅读了很多关于线程,选择函数,非阻塞选项等的文档。 但我找不到任何关于如何处理客户端故障的文档。

更具体地说,使用线程和阻塞套接字(不是最好的想法,我知道,但我只是运行一些测试),当客户端连接速度太慢时会发生什么?或当客户端没有正确关闭连接(或根本没有关闭它)时会发生什么?我的套接字会被阻止吗?或线程永远不会完成?

如何处理这种情况?

2 个答案:

答案 0 :(得分:2)

使用阻塞套接字时,您有几个选择。

一个是每个客户端有一个线程,这样当你等待信息时,你阻塞的时间并不重要。请注意,当连接关闭时,阻止的操作将终止。您可以阅读有关此here的更详细说明。

多线程的替代方法是使用select。这允许您等待多个文件描述符,直到文件描述符的某个子集准备就绪,因为它们不会阻塞。因此,基本上不是在readwrite期间阻止单个文件描述符,而是阻止select,然后您知道以后不会阻止read/write

最后,您可以使用异步I / O函数aio_readaio_write,这些函数将从执行的调用线程异步执行读/写。

答案 1 :(得分:1)

通常,套接字具有一些可由客户端控制的超时值。如果连接运行得太慢,或者由于某种原因连接中断(例如,互联网连接不良),套接字操作可能会继续阻塞,直到超时到期。使用Linux套接字,当超时到期时,您将获得一个ETIMEDOUT错误,然后您可以稍后处理。

超时的典型值大约为60-300秒,但如果您想更快地了解超时,可以将它们设置得更低。您也可以将其设置为无限,但如果您使用直接阻止调用,则不建议这样做,因为您可以永久挂起线程。

在Linux(以及使用BSD socket API的任何其他系统)上,您可以使用

更改套接字超时
struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;

setsockopt(socket, SOL_SOCK, SO_RCVTIMEO, &timeout, sizeof(struct timeval));