Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to simulate abnormal case for socket/tcp programming in linux, such as terminating one side of connection?

Tags:

c

linux

tcp

sockets

i am learning to use SO_SNDTIMEO and SO_RCVTIMEO to check the timeout. It is easy to use with read socket. But when i want to check write timeout, it always return successful. Here is what i did:(all in blocking mode)

  1. close the client read socket and exit before server start write
  2. terminate the client before server start write
  3. unplug the cable of server after accept but before write

well, it seems all these case write just return sucessfully. I think the reason should be that port is resource managed by os, and at the client side, after program gone, the tcp connection still shows FIN_WAIT2 state.

so, is there any convenient way to simulate some cases that write can receive errors such as EPIPE, EAGAIN?

like image 583
xgwang Avatar asked Jun 26 '12 03:06

xgwang


3 Answers

How to get the error EAGAIN?
To get the error EAGAIN, you need to be using Non-Blocking Sockets. With Non-Blocking sockets, you need to write huge amounts of data (and stop receiving data on the peer side), so that your internal TCP buffer gets filled and returns this error.

How to get the error EPIPE?
To get the error EPIPE, you need to send large amount of data after closing the socket on the peer side. You can get more info about EPIPE error from this SO Link. I had asked a question about Broken Pipe Error in the link provided and the accepted answer gives a detailed explanation. It is important to note that to get EPIPE error you should have set the flags parameter of send to MSG_NOSIGNAL. Without that, an abnormal send can generate SIGPIPE signal.

Additional Note
Please note that it is difficult to simulate a write failure, as TCP generally stores the data that you are trying to write into it's internal buffer. So, if the internal buffer has sufficient space, then you won't get an error immediately. The best way is to try to write huge amounts of data. You can also try setting a smaller buffer size for send by using setsockopt function with SO_SNDBUF option

like image 120
Jay Avatar answered Nov 14 '22 21:11

Jay


You can simulate errors using fault injection. For example, libfiu is a fault injection library that comes with an example project that allows you to simulate errors from POSIX functions. Basically it uses LD_PRELOAD to inject a wrapper around the regular system calls (including write), and then the wrapper can be configured to either pass through to the real system call, or return whatever error you like.

like image 40
Eric Melski Avatar answered Nov 14 '22 23:11

Eric Melski


You could set the receive buffer size to be really small on one side, and send a large buffer on the other. Or on the one side set the send buffer small and try to send a large message.

Otherwise the most common test (I think) is to let the server and client talk for a while, and then remove a network cable.

like image 23
Some programmer dude Avatar answered Nov 14 '22 21:11

Some programmer dude