Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分叉多个进程以侦听()/accept()_C_Unix_Process_Fork - Fatal编程技术网

分叉多个进程以侦听()/accept()

分叉多个进程以侦听()/accept(),c,unix,process,fork,C,Unix,Process,Fork,报告所有侦听连接都属于具有相同inode的套接字,这是有意义的,因为套接字在父节点中创建一次,并且每个子节点都共享它 因此,我认为如果我想要在同一个地址:port元组上有多个侦听器,我应该为每个孩子执行bind()-listen()序列。对吗 但是这会导致错误:bind()返回EINVAL,我只创建了一个子项: % lsof -i :9900 for(i=0;i

报告所有侦听连接都属于具有相同inode的套接字,这是有意义的,因为套接字在父节点中创建一次,并且每个子节点都共享它

因此,我认为如果我想要在同一个
地址: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();
    }
}