6

我正在学习使用SO_SNDTIMEOSO_RCVTIMEO来检查超时。与读取套接字一起使用很容易。但是当我想检查写入超时时,它总是返回成功。这是我所做的:(全部处于阻塞模式)

  1. 在服务器开始写入之前关闭客户端读取套接字并退出
  2. 在服务器开始写入之前终止客户端
  3. 在接受之后但在写入之前拔下服务器的电缆

好吧,似乎所有这些案例都成功返回了。我认为原因应该是端口是由os管理的资源,并且在客户端,程序消失后,tcp连接仍然显示FIN_WAIT2状态。

那么,有没有什么方便的方法来模拟某些write可以接收错误的情况,例如EPIPEEAGAIN

4

3 回答 3

5

如何得到错误EAGAIN?
要获得 EAGAIN 错误,您需要使用非阻塞套接字。使用非阻塞套接字,您需要写入大量数据(并停止在对等端接收数据),以便您的内部 TCP 缓冲区被填满并返回此错误。

如何得到错误 EPIPE?
要得到错误EPIPE,需要在对端关闭socket后发送大量数据。您可以从此 SO Link获得有关 EPIPE 错误的更多信息。我在提供的链接中询问了有关 Broken Pipe Error 的问题,接受的答案给出了详细的解释。需要注意的是,要获得 EPIPE 错误,您应该将 send 的 flags 参数设置为 MSG_NOSIGNAL。否则,异常发送会产生 SIGPIPE 信号。

附加说明
请注意,很难模拟写入失败,因为 TCP 通常会将您尝试写入的数据存储到其内部缓冲区中。因此,如果内部缓冲区有足够的空间,那么您不会立即收到错误消息。最好的方法是尝试写入大量数据。您还可以尝试使用带有 SO_SNDBUF 选项的setsockopt函数设置较小的发送缓冲区大小

于 2012-06-26T05:20:03.790 回答
5

您可以使用故障注入来模拟错误。例如,libfiu是一个故障注入库,它带有一个示例项目,允许您模拟来自 POSIX 函数的错误。基本上,它用于LD_PRELOAD在常规系统调用(包括 )周围注入一个包装器write,然后可以将包装器配置为传递给真正的系统调用,或者返回您喜欢的任何错误。

于 2012-06-26T05:37:06.157 回答
1

您可以在一侧将接收缓冲区大小设置为非常小,而在另一侧发送一个大缓冲区。或者一方面将发送缓冲区设置为小,然后尝试发送大消息。

否则最常见的测试(我认为)是让服务器和客户端通话一段时间,然后拔掉网线。

于 2012-06-26T05:18:57.567 回答