父级和分叉子级之间的文件描述符共享
我是网络编程的初学者..
我遵循史蒂文斯并可靠地实现UDP服务器。
我有一个问题。
当子进程被分叉时,子进程中的父套接字 fd 会发生什么?我读到它们被继承,这意味着我们在父级和子级中有两个套接字 fd 副本?我们是否需要关闭子进程中继承的父套接字 fd(史蒂文斯代码没有这样做)
如何关闭子进程中的父套接字(使用 close () ??)而不是客户端请求到达的套接字(我应该保留这个)打开)?
如果我太天真了……请原谅。
感谢您的帮助!
I am a beginner in network programming..
i follow stevens and implementing UDP server with reliability.
i have a question.
when a child is forked what happens to parent socket fd in child ...? i read that they get inherited that means we have two copies of socket fd in parent and child ?? do we need to close the inherited parent socket fd in child (stevens code doesnt do that)
how does one close parent fds in child (using close () ??) but not the socket on which the client request arrived ( i should keep this open)?
If i am being naive..please excuse me.
Thanks for the help !!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
文件描述符在分叉时确实是“继承”的,但仅限于它们连接到的套接字,并且关闭文件描述符只会关闭与该套接字(或文件,如果我们是)关联的最后一个套接字。处理文件)。
你通常做的是建立套接字,然后分叉。在父进程(fork 返回非零的进程)中,您可以继续使用
close(fd)
关闭文件描述符,如果不这样做,您最终将用完文件描述符在父进程中。这适用于流(例如 TCP)套接字,其中您有一个服务器套接字侦听连接,并且每个已建立的连接都有一个套接字。但是,您使用的是 UDP,因此实际上只有一个套接字,如果您打算在父进程中继续使用它,则需要弄清楚如何在父进程和子进程之间共享它。两者都可以继续使用它,但谁读什么以及按什么顺序发送内容几乎是随机的。在这种情况下,您通常有某种多路复用进程,它接收数据包,并根据某些消息内容(在 TCP 中,它是源 ip)将它们转发到适当的子进程(通过其他机制,例如管道或其他套接字) /端口和目标 ip/端口元组)。正如 Matt 指出的那样,使用 shutdown 实际上会使所有涉及的套接字都无法使用(通常是不可写的,但您可以指定这一点)。在 TCP 中,这可能会触发 FIN 数据包的发送,从而有效地启动连接的断开,但您仍然可以接收数据,直到远程端确认 FIN。
File descriptors are indeed 'inherited' when forking, but only with respect to what socket they're connected to, and closing the file descriptor will only close the socket if it's the last one associated with that socket (or file, if we're dealing with files).
What you usually do is you establish the socket, and then you fork. In the parent process (the one where fork returned non-zero) you can go ahead and close the file descriptor using
close(fd)
, if you don't you'll eventually run out of file descriptors in the parent process. This is for stream (e.g. TCP) sockets, where you have one server socket listening for connections, and one socket per established connection. However, you're using UDP, so there is in fact only one socket, and if you intend to keep using it in the parent process, you'll need to figure out how to share it between parent and child process. Both can continue using it, but it'll be almost random who reads what, and in what order stuff is sent. In this case you usually have some kind of multiplexing process, which receives the packets, and forwards them to the appropriate child (per some other mechanism, such as pipes or other sockets) based on some message content (in TCP, it's the source ip/port and destination ip/port tuple).As Matt pointed out, using
shutdown
will in fact render the socket unusable (usually unwritable, but you can specify this) for all involved. In TCP, this could trigger the sending of a FIN-packet, effectively initiating the tear-down of the connection, but you're still able to receive data until the remote end acknowledges the FIN.