简体   繁体   中英

A way to detect which side of the socket peers triggered the disconnection

Is there is a way for a process to detect which side of a TCP connection triggered the first FIN? My Process or Network entity that my process communicates with.

Let's say I have a multithreaded process on Linux that one of its sockets handles an established TCP socket with other network entity.

Theoretically, one thread in my process can close the socket that is handled (select/read/send) by a second thread.

Is there are way to detect which side of the connection triggered first the disconnection?

Just associate some kind of application-level structure with the socket. Have a rule that if a thread wishes to shutdown or terminate the connection, it must so indicate in the application-level structure.

All of the threads in a process are supposed to be cooperating. You shouldn't need to "reach into" a thread to find out what it did or make it do the right thing. It should be coded to inform other threads of what they need to know.

Is there is a way for a process to detect which side of a TCP connection triggered the first FIN?

tcpdump can show you it. This is an example. A server application listens on 7752 port. A client first established a connection and then the client closes the connection. So this is the output:

# tcpdump -i lo 'tcp[13] & 1 != 0'
11:12:28.613424 IP localhost.50631 > localhost.7752: Flags [F.], seq 12878459, ack 4245407789, win 276, options [nop,nop,TS val 3690514841 ecr 3690513840], length 0
11:12:28.613720 IP localhost.7752 > localhost.50631: Flags [F.], seq 1, ack 1, win 256, options [nop,nop,TS val 3690514841 ecr 3690514841], length 0

If you are using select() or something like it ( poll() , epoll() , kqueue() , etc.), then the socket should always be monitored for read readiness. When a recv() (or read() ) on a socket returns 0 , it means the other end has issued a shutdown on the socket (either with a call to shutdown() or close() ).

If you want an API to detect whether or not you have already issued a half close with shutdown() , a send() (or write() ) on the socket will trigger SIGPIPE . If SIGPIPE is ignored, or if send() is passed the MSG_NOSIGNAL flag, then an EPIPE error will be the result instead.

If a thread has already called close() on a socket, it would be an error for that thread to attempt any I/O on the socket. The result can be non-deterministic since the socket file descriptor may get reused by the process for some other purpose. This kind of error is similar to having a stale pointer to freed memory that has been allocated by some other thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM