IP地址和端口号是否可以唯一地标识进程ID?
我正在寻找一种方法来获取相应的进程ID,给定一个IP地址和一个端口号,但我不确定这些ip / port对是否可以唯一地识别一个pid。
答案 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。