I'm trying to implement code that enumerate all existing TCP connections per process (similar to netstat -lptn). I prefer to implement it myself and not to rely on netstat. In order to do that, I'm parsing data from /proc/<PID>/net/tcp.

I saw that a number of TCP connections are listed under /proc/<PID>/net/tcp but not listed by netstat -lptn command.

For example I see that /proc/1/net/tcp and /proc/2/net/tcp have several TCP connections (tried on Ubuntu 16). As I understand, /proc/1/net/tcp is related to the /sbin/init process which should not have any TCP connection. The /proc/2/net/tcp is related to kthreadd which also should not have any TCP connection.


2 Answers 2


There are many misunderstandings in your approach. I'll go over them one by one.

  1. Sockets are not associated with a specific process. When a socket is created its reference count is 1. But through different methods such as dup2, fork, and file descriptor passing it's possible to create many references to the same socket causing its reference count to increase. Some of these references can be from an open file descriptor table, which itself can be used by many threads. Those threads may belong to the same thread group (PID) or different thread groups. When you use the -p flag for netstat it will enumerate the sockets accessible to each process and try to find a process for each known socket. If there are multiple candidate processes, there is no guarantee that it shows the process you are interested in.
  2. /proc/<PID>/net/tcp does not only list sockets related to that process. It lists all TCPv4 sockets in the network namespace which that process belongs to. In the default configuration all processes on the system will belong to a single network namespace, so you'll see the same result with any PID. This also explains why a thread/process which doesn't use networking has contents in this file. Even if it doesn't use networking itself it still belongs to a network namespace in which other processes may use networking.
  3. /proc/<PID>/net/tcp contains both listening and connected sockets. When you pass -l to netstat it will show you only listening sockets. To match the output closer you'd need -a rather than -l.
  4. /proc/<PID>/net/tcp contains only TCPv4 sockets. You need to use /proc/<PID>/net/tcp6 as well to see all TCP sockets.

If you are only interested in sockets in the same namespace as your own process you don't need to iterate through different PIDs. You can instead use /proc/net/tcp and /proc/net/tcp6 since /proc/net is a symlink to /proc/self/net.


Use /proc/<pid>/fd - this lists all the open file descriptors, including sockets that the process is using. e.g.

total 0
dr-xr-xr-x. 9 user user  0 Apr 22 23:30 ../
dr-x------. 2 user user  0 Apr 22 23:30 ./
lr-x------. 1 user user 64 Apr 22 23:30 4 -> pipe:[640683476]
lrwx------. 1 user user 64 Apr 22 23:30 3 -> socket:[640754628]
lrwx------. 1 user user 64 Apr 22 23:30 2 -> /dev/pts/10
l-wx------. 1 user user 64 Apr 22 23:30 1 -> /home/user/my_sockets.txt
lrwx------. 1 user user 64 Apr 22 23:30 0 -> /dev/pts/10

You can then find the corresponding entry (e.g. 640754628) from /proc/<pid>/net/tcp -> inode[6] to get all the details of the socket - e.g.

  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
1864: 0100007F:A650 0100007F:18EB 01 00000000:00000000 00:00000000 00000000   500        0 640754628 1 0000000000000000 20 4 30 10 -1

( above example is a local connection to )

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .