IP地址和端口号是否可以唯一地标识进程ID?

时间:2012-01-04 18:07:59

标签: c++ c sockets tcp udp

IP地址和端口号是否可以唯一地标识进程ID?

我正在寻找一种方法来获取相应的进程ID,给定一个IP地址和一个端口号,但我不确定这些ip / port对是否可以唯一地识别一个pid。

4 个答案:

答案 0 :(得分:12)

不一定。如果在进程中打开/接受套接字然后分叉,则子进程也打开套接字,因此两个进程使用IP地址和端口号。

答案 1 :(得分:1)

正如乔纳森所指出的那样,这种关系不一定是唯一的。例如,有服务器实现(apache / prefork)使用子进程同时处理请求。

但是你仍然可以使用特定的端口/地址获取进程列表(尽管单个端口/地址对可能有多个条目),也许在您的特定情况下这是一个可行的解决方案:

例如,在Windows中,您可以使用GetExtendedTcpTable功能,将TableClass参数设置为其中一个TCP_TABLE_OWNER_MODULE_*值。这将返回一个表,其中包含所有当前TCP端点的本地和远程地址/端口和进程ID。

在Linux上肯定有类似的方式(虽然我不知道如何做到这一点......),因为这正是netstat -p程序的作用。

答案 2 :(得分:1)

同时,只有一个进程可以绑定到给定端口,因此给定一个端口,我们最多只能有一个进程监听它。 是的,多个进程可以发送&通过相同的端口接收但只有一个进程绑定到端口。

e.g。在下面的代码中,一个得到“服务器:bind:地址已经在使用”错误。然后,如果我们运行lsof -i:2100,我们只能在端口2100上侦听一个进程ID。

#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);

}

答案 3 :(得分:0)

在Windows计算机上,您可以获取侦听应用程序的进程ID。请参阅this question