Могут ли IP-адрес и номер порта вместе однозначно идентифицировать идентификатор процесса? - PullRequest
4 голосов
/ 04 января 2012

Могут ли IP-адрес и номер порта вместе однозначно идентифицировать идентификатор процесса?

Я ищу способ получить соответствующий идентификатор процесса, учитывая IP-адрес и номер порта, но я 'я не уверен, могут ли такие пары ip / port однозначно идентифицировать один pid.

Ответы [ 4 ]

12 голосов
/ 04 января 2012

Не обязательно.Если сокет открывается / принимается в процессе, а затем разветвляется, дочерний процесс также имеет открытый сокет, поэтому IP-адрес и номер порта используются двумя процессами.

1 голос
/ 09 марта 2012

За раз, только один процесс может привязаться к данному порту, следовательно, при наличии порта мы можем иметь не более одного процесса, который прослушивает его.Да, несколько процессов могут отправлять и получать через один и тот же порт, но только один процесс связывается с портом.

например, в следующем коде выдается ошибка "server: bind: Address Уже используется" .Затем, если мы запустим lsof -i: 2100, мы получим только один идентификатор процесса, слушающий порт 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);

}
1 голос
/ 04 января 2012

Как отметил Джонатан, связь не обязательно уникальна. Например, существуют серверные реализации (apache / prefork), которые используют дочерние процессы для одновременной обработки запросов.

Но вы в любом случае можете получить список процессов, использующих определенный порт / адрес (хотя для одной пары порт / адрес может быть несколько записей), возможно, в вашем конкретном случае это жизнеспособное решение:

Например, в Windows вы можете использовать функцию GetExtendedTcpTable , задав для параметра TableClass одно из значений TCP_TABLE_OWNER_MODULE_*. Это возвращает таблицу, содержащую локальный и удаленный адрес / порт и идентификатор процесса для всех текущих конечных точек TCP.

В Linux, безусловно, есть похожие способы (хотя я наизусть не знаю, как это сделать ...), поскольку именно это и делает программа netstat -p.

0 голосов
/ 04 января 2012

На компьютере с Windows вы можете получить идентификатор процесса для прослушивающего приложения.См этот вопрос .

...