В C с программой сокетов я пытаюсь вставить getpeername () и getsockname в сокет server для печати IP-адреса сокета сервера и сокета клиента на стороне сервера. Примечание: мой серверный сокет использует INADDR_ANY. Я помещаю getpeername () и getsockname () в разные позиции:
1 / перед bind (): IP-адрес и клиентского, и серверного сокета - 0.0.0.0
2 / после bind (): снова IP-адрес клиентского и серверного сокетов 0.0.0.0
3 / после accept (): IP-адрес клиента - 10.0.2.15, а сокет сервера - по-прежнему 0.0.0.0.
Они правы? Вы можете объяснить, почему в этих случаях я получил 0.0.0.0 вместо конкретного адреса?
Примечание: на мой взгляд, я должен получить конкретный IP-адрес серверного сокета после bind (), потому что bind () уже привязывает серверный сокет к определенному IP-адресу. И после accept () я думаю, что и клиентский сокет, и серверный сокет тоже должны иметь конкретный IP-адрес, а не 0.0.0.0.
1 ответ
Я не могу воспроизвести вашу проблему; например рассмотреть возможность
#include <unistd.h>
#include <netinet/ip.h>
#include <sys/socket.h>
int main(void)
{
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = 0,
.sin_addr = { INADDR_ANY },
};
int fd;
int c_fd;
struct sockaddr_in p_addr;
socklen_t a_len = sizeof p_addr;
fd = socket(AF_INET, SOCK_STREAM, 0);
bind(fd, (void const *)&addr, sizeof addr);
getpeername(fd, (void *)&p_addr, &a_len);
getsockname(fd, (void *)&p_addr, &a_len);
listen(fd, 10);
c_fd = accept(fd, NULL, NULL);
getpeername(c_fd, (void *)&p_addr, &a_len);
getsockname(c_fd, (void *)&p_addr, &a_len);
}
Запуск его через strace
и подключение к адресу привязки показывает
$ strace ./a.out
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getpeername(3, 0x7ffdcf3af130, [16]) = -1 ENOTCONN (Transport endpoint is not connected)
getsockname(3, {sa_family=AF_INET, sin_port=htons(60093), sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
listen(3, 10) = 0
accept(3, NULL, NULL) = 4
getpeername(4, {sa_family=AF_INET, sin_port=htons(35048), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(60093), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
В ваших случаях 1 + 2 сервер отсутствует, и getpeername()
завершится ошибкой с ENOTCONN
.
Перед accept()
getsockname
возвращает 0.0.0.0
, потому что вы слушаете INADDR_ANY
.
Но после accept()
getsockname()
вернет локальный адрес.
Похожие вопросы
Связанные вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.