chavaone
chavaone

Reputation: 183

How to get the pid of a process that is listening on a certain port programmatically?

I have to write a SNMP module which monitor a certain server application that I have written too. The problem is that I have to know if this application is running and I should be able to kill it whenever I can.

I know the port where the application is listening (reading the application configuration file) and I can try to bind this port to a socket in order to know if it is (or isn't) being used by my application or another which is enough for my module. Here is the code:

int
get_server_status()
{
        struct sockaddr_in local;
        int port,sockfd;

        if (parse_config_file(&port,NULL,CONFIG_FILE_PATH) == -1)
                return -1; //Error

        if ((sockfd = socket ( AF_INET, SOCK_STREAM, 0 )) < 0)
                return -1; //Error

        local.sin_family = AF_INET;
        local.sin_port = htons ( port );
        local.sin_addr.s_addr = inet_addr ("127.0.0.1");

        if (bind(sockfd, (struct sockaddr *) &local, sizeof (local) ) < 0 ){
                if(errno == EADDRINUSE)
                        return 1; //Port being used
                else
                        return -1; //Error
        }else{
                close(sockfd);
                return 0;         //Port not being used

        }
}

The problem comes when I need to kill the application, I don't know neither its PID nor how to get it. I can get is using netstat -tln <port>but I don't know how to do it programmatically. Any ideas??

Upvotes: 5

Views: 5272

Answers (2)

ugoren
ugoren

Reputation: 16441

Like netstat, you should read /proc/net/tcp.

Interpreting it:

  1. The second field, titled local_address, is the IP and port. 00000000:0050 would be HTTP (the port number is in hex).
  2. The 4th field, titled st, is the state. A is TCP_LISTEN.
  3. The 10th field, titled inode is the inode number (decimal this time).
  4. For each process, /proc/pid/fd/ contains an entry for each open file descriptor. ls -l for socket descriptors shows that it's a link to socket:[nnnnnn]. The number nnnnnn should match the inode number from /proc/net/tcp.

This makes finding the process quite tiresome, but possible.
Finding the right line in /proc/net/tcp isn't difficult, and then you can get the inode number.
Finding the process requires you to scan all processes, looking for one which refers this inode number. I know no better way.

Upvotes: 6

B-K
B-K

Reputation: 359

Certainly you could fork netstat, or else do what netstat does (I assume you are working on some kind of unix):

The /proc/net/tcp 'file' shows the current tcp sockets. each line gives info about the socket. The local_address field shows the local address in IP:PORT format, in hexadecimal. From there you can find which socket is the one corresponding to the listening port. Then you get the corresponding inode filed and you should search for it in all /proc//fd links in the form of

-> socket:[]

Hope it helps

Upvotes: 3

Related Questions