flyingbin
flyingbin

Reputation: 1097

Can an IP address and a port number together uniquely identify a process ID?

Can an IP address and a port number together uniquely identify a process ID?

I'm looking for a way to get the corresponding process ID, given an IP address and a port number, but I'm not sure whether such ip/port pairs can uniquely identify one pid.

Upvotes: 4

Views: 1719

Answers (5)

Dudu
Dudu

Reputation: 1292

To add a Windows specific counter example:

Windows has a http.sys (the kernel-mode HTTP protocol listener) service which enables port sharing by different applications. https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/net-tcp-port-sharing

Upvotes: 0

Sanborn
Sanborn

Reputation: 13

At a time, only one process can bind to a given port, hence given a port we can have at most one process listening on it. Yes multiple processes can send & receive through the same port but only one process binds to a port.

e.g. in the following code one gets a "server:bind: Address Already in use" error. Then, if we run lsof -i:2100 we get only one process id listening on port 2100.

#define SERVERPORT "2100"
#define BUF_MAX 1024
#define BACKLOG 10
int data_connection(char* portno)
{
    struct addrinfo hints,*res,*clientinfo;
    int rv,datafd,yes=1,new_fd;
    char buf[BUF_MAX];
    struct sockaddr_storage their_addr;
    socklen_t addr_size;

    memset(&hints,0,sizeof(hints));
    hints.ai_family=AF_UNSPEC; 
    hints.ai_socktype=SOCK_STREAM;//connnection oriented.
    hints.ai_flags=AI_PASSIVE;

    if ((rv = getaddrinfo(NULL, portno, &hints, &res)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }
    for(clientinfo=res;clientinfo!=NULL;clientinfo=clientinfo->ai_next)
    {
        if((datafd=socket(clientinfo->ai_family,clientinfo->ai_socktype,clientinfo->ai_protocol))==-1)
        {
            perror("server:datasocket");
            continue;
        }
        break;
    }

    if(setsockopt(datafd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))==-1)
    {
        perror("setsockopt");
        exit(1);
    }

    if(bind(datafd,clientinfo->ai_addr,clientinfo->ai_addrlen)<0)
    {
        perror("server:bind");
        exit(1);
    }
    if(listen(datafd,BACKLOG)<0)
    {
        perror("server:listen");
        exit(1);
    }
    addr_size=sizeof(their_addr);
    if((new_fd=accept(datafd,(struct sockaddr*)&their_addr,&addr_size))<0)
    {
        perror("server:accept");
        exit(1);
    }
    close(datafd);
    datafd=new_fd;

    return datafd;
}
int main()
{
    int datafd;
    fork();
    datafd=data_connection(SERVERPORT);

}

Upvotes: 1

MartinStettner
MartinStettner

Reputation: 29174

As Jonathan pointed out, the relation is not necessarily unique. For instance, there are server implementations (apache/prefork) which use child processes to handle requests concurrently.

But you can get the list of processes using a specific port/address anyway (although there might be multiple entries for a single port/address pair), perhaps in your specific case this is a viable solution:

In Windows, for example, you can use the GetExtendedTcpTable function, setting the TableClass parameter to one of the TCP_TABLE_OWNER_MODULE_* values. This returns a table containing local and remote address/port and process ID for all current TCP endpoints.

On Linux there are certainly similar ways (although I do not know by heart how to do it...), since this is exactly what the netstat -p program does.

Upvotes: 1

Bukes
Bukes

Reputation: 3718

On a windows machine, you can obtain the process ID for a listening application. See this question.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 754620

Not necessarily. If a socket is opened/accepted in a process, and it then forks, the child process also has the socket open, so the IP address and port number are used by two processes.

Upvotes: 12

Related Questions