1. Если я свяжу этот сокет с портом и прослушу этот порт, будет ли также сокет, который был разветвлен перед этими двумя вызовами, прослушать и привязать к тому же порту?
Как только вы иметь дескриптор файла (созданный с помощью 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.
2. Если я использую accept на сокете, и сокет принимает соединение и связывается с клиентским сокетом: Будут ли также сокеты, которые были разветвлены, соединены с этим клиентским сокетом?
Нет. Этот вопрос предполагает существование связи / соединения между сокетом, созданным accept
, и сокетом, в котором был вызван accept
, но такой связи / соединения нет (ни в одном из процессов).
3. Могу ли я использовать сокет, открытый для соединений TCP, в качестве получателя TCP и отправителя UDP?
4. Могу ли я использовать сокет, открытый для соединений TCP, в качестве приемника UDP и отправителя TCP?
Нет. Сокет - это либо сокет TCP, либо сокет UDP. Вы не можете отправлять / получать пакеты UDP через сокет TCP, и вы не можете отправлять / получать пакеты TCP через сокет UDP. Невозможно даже попробовать.
Однако порты TCP и UDP независимы, поэтому вы можете использовать TCP-порт 1234 и UDP-порт 1234 одновременно (используя два разных сокета).
5. Если у меня есть сокет, который был открыт для соединений TCP: Могу ли я использовать sendto с последними 2 аргументами NULL без проблем?
Да. send
может быть вызвано для сокетов TCP, а send
определяется в терминах sendto
с NULL
и 0
для последних двух аргументов.
Согласно man 2 send
на моем (GNU / Linux) system:
send(sockfd, buf, len, flags);
эквивалентно sendto(sockfd, buf, len, flags, NULL, 0);
Фактически, вы должны установить два последних аргумента в NULL
и 0
с сокетом TCP.
В соответствии с man 2 sendto
в моей (GNU / Linux) системе:
Если sendto()
используется для соединения- В режиме (SOCK_STREAM
, SOCK_SEQPACKET
) сокета аргументы dest_addr
и addrlen
игнорируются (и ошибка EISCONN
может быть возвращена, если они не NULL
и 0
)
6. Могу ли я использовать на клиентском сокете, к которому был подключен TCP, recvfrom с последними 2 аргументами NULL?
Да. recv
можно вызывать для сокетов TCP, а recv
определяется в терминах recvfrom
с NULL
для последних двух аргументов.
Согласно man 2 recv
на моем (GNU / Linux) система:
recv(sockfd, buf, len, flags);
эквивалентна recvfrom(sockfd, buf, len, flags, NULL, NULL);