分叉多个进程以侦听()/accept()
报告所有侦听连接都属于具有相同inode的套接字,这是有意义的,因为套接字在父节点中创建一次,并且每个子节点都共享它 因此,我认为如果我想要在同一个分叉多个进程以侦听()/accept(),c,unix,process,fork,C,Unix,Process,Fork,报告所有侦听连接都属于具有相同inode的套接字,这是有意义的,因为套接字在父节点中创建一次,并且每个子节点都共享它 因此,我认为如果我想要在同一个地址:port元组上有多个侦听器,我应该为每个孩子执行bind()-listen()序列。对吗 但是这会导致错误:bind()返回EINVAL,我只创建了一个子项: % lsof -i :9900 for(i=0;i
地址:port
元组上有多个侦听器,我应该为每个孩子执行bind()-listen()序列。对吗
但是这会导致错误:bind()
返回EINVAL,我只创建了一个子项:
% lsof -i :9900
for(i=0;i
我做错了什么?可移植的Unix方法是在主进程/线程中调用
套接字
,绑定
,侦听
<然后子进程/线程调用code>accept
您可能希望在bind
之前设置SO\u REUSEADDR
选项,以便快速重启服务器
在Linux上,每个孩子都可以创建自己的套接字,设置
以便重用端口
,然后调用绑定
,侦听
,接受
。见:
SO\u重用端口
允许将多个AF_INET
或AF_INET6
套接字绑定到
相同的套接字地址。此选项必须在每个服务器上设置
调用bind
在插座上。为了防止端口劫持,绑定到同一地址的所有进程必须具有相同的有效UID。此选项可用于TCP和UDP
插座
对于TCP套接字,此选项允许通过为每个线程使用不同的侦听器套接字来改进多线程服务器中的accept
负载分布。这提供了更好的解决方案
与传统技术相比,如
使用单个accept
ing线程分发连接,或使用多个线程竞争accept
从同一个插座
对于UDP套接字,使用此选项可以提供更好的
将传入数据报分发到多个进程(或
(线程)与传统的
多个进程竞争在同一台计算机上接收数据报
插座
检查返回值和errno。第二个(以及随后的)可能会失败EADDRINUSE@wildplasser. 谢谢你的回复。因此,So_REUSEPORT选项是不够的?@wildplasser。可能我不清楚——bind()返回循环中除第一个以外的所有元素的EINVAL。只需检查返回值。这是有原因的。@wildplasser,正如我之前写的,返回值是EINVAL。感谢您的反馈。在循环中为每个创建的子项设置
SO\u REUSEPORT
和SO\u REUSEADDR
,没有任何帮助,即bind()
仍然无法使用EINVAL。创建每个子套接字,设置SO_REUSEPORT,然后有效地绑定listen accept,这与多次运行程序是一样的,而且确实有效。@标记您的第一句话听起来不像是在做正确的事情。在主进程中,您执行socket
,SO\u REUSEADDR
,bind
,listen
。在child中,您只接受。在父级中有一个侦听器是一个瓶颈。我正在尝试(我还在学习socket编程)创建多个侦听器(在同一地址:port
上),每个侦听器都在自己的子进程中。我知道这不能扩展,pthread是首选,但现在我只想让这个简单的东西工作。
% lsof -i :9900
for (i = 0; i < MAX_PROCS; i++) {
pid = fork();
if (pid == 0) {
srv.sin_family = AF_INET;
srv.sin_addr.s_addr = INADDR_ANY;
srv.sin_port = htons(9900);
bind(fd, (const struct sockaddr *)&srv, sizeof srv);
...
listen();
accept();
}
}