我有一个进程,它必须建立一个服务器来接受TCP连接,并创建一些子进程来完成这项工作。我创建一个TCP套接字(不监听、绑定或接受),然后创建叉。我有以下问题:
如果我将该套接字绑定到一个端口并侦听该端口,那么该套接字也会在这两个调用之前分叉,侦听并绑定到同一个端口吗?如果我在套接字上使用
我知道fd表是父亲和孩子之间共享的,但是我不知道父亲进程中发生在套接字上的任何更改是否也会发生在孩子身上。
。
发布于 2020-01-12 22:17:20
如果我将该套接字绑定到一个端口并侦听该端口,那么该套接字是否也会在这两个调用之前进行分叉,侦听并绑定到同一个端口?
一旦您有了一个文件描述符(如socket或accept创建的),对该文件描述符的更改将反映在该描述符在所有进程中的克隆中。
由于不能绑定套接字两次,所以可以使用以下内容验证我的声明。(它是用Perl编写的,但是C程序员应该能够毫无问题地阅读它。die抛出一个异常,$!为strerror(errno),$!{EINVAL}等效于errno == EINVAL)。
#!/usr/bin/perl
use 5.014;
use warnings;
use Socket qw( pack_sockaddr_in AF_INET SOCK_STREAM INADDR_ANY SOMAXCONN );
socket(my $socket, AF_INET, SOCK_STREAM, 0)
   or die("socket: $!\n");
defined( my $pid = fork() )
   or die("fork: $!\n");
if (!$pid) {
   bind($socket, pack_sockaddr_in(0, INADDR_ANY))
      or die("bind: $!\n");
   listen($socket, SOMAXCONN)
      or die("listen: $!\n");
   exit;
}
waitpid($pid, 0) > 0
   or die("waitpid: $!\n");
if (bind($socket, pack_sockaddr_in(0, INADDR_ANY))) {
   say "Socket bound again. bind doesn't transcend processes.";
} else {
   if ($!{EINVAL}) {
      say "Socket already bound. bind transcends processes.";
   } else {
      die("bind in parent: $!\n");
   }
}输出:
Socket already bound. bind transcends processes.如果我在套接字上使用
,而套接字接受连接并链接到客户端套接字:分叉的套接字也会连接到那个客户端套接字吗?
不是的。这个问题的前提是accept创建的套接字与调用accept的套接字之间存在链接/连接,但是没有任何这样的链接/连接(在任何进程中)。
3.是否可以使用为TCP连接打开的套接字作为TCP接收方和UDP发送方?
4.是否可以使用为TCP连接打开的套接字作为UDP接收方和TCP发送方?
不是的。套接字要么是TCP套接字,要么是UDP套接字。不能通过TCP套接字发送/接收UDP数据包,也不能通过UDP套接字发送/接收TCP数据包。根本没办法试一试。
但是,TCP和UDP端口是独立的,因此您可以同时使用TCP端口1234和UDP端口1234 (使用两个不同的套接字)。
5.如果我有一个为TCP连接打开的套接字:我是否可以使用sendto与最后2个参数为NULL,而不存在任何问题?
是。可以在TCP套接字上调用send,对于最后两个参数,send是用带有NULL和0的sendto定义的。
根据我的(GNU/Linux)系统上的man 2 send:
send(sockfd, buf, len, flags);等同于sendto(sockfd, buf, len, flags, NULL, 0);
实际上,必须使用TCP套接字将最后两个参数设置为NULL和0。
根据我的(GNU/Linux)系统上的man 2 sendto:
如果在连接模式(
SOCK_STREAM,SOCK_SEQPACKET)套接字上使用sendto(),则忽略参数dest_addr和addrlen(当它们不是NULL和0时,可能返回错误EISCONN)。
6.我可以在客户端套接字上使用TCP将recvfrom与最后2个参数NULL连接起来吗?
是。可以在TCP套接字上调用recv,并为最后两个参数用带有NULL的recvfrom定义recv。
根据我的(GNU/Linux)系统上的man 2 recv:
recv(sockfd, buf, len, flags);等同于recvfrom(sockfd, buf, len, flags, NULL, NULL);
https://stackoverflow.com/questions/59708009
复制相似问题