Я не могу воспроизвести вашу проблему;например, рассмотрим
#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
и подключение к bind-адресу показывает
$ 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()
вернет местный адрес.