getpeername () не работает с подключениями к localhost - PullRequest
0 голосов
/ 17 сентября 2009

РЕДАКТИРОВАТЬ: Решая проблему, если я слушаю порт 54321 и локальный процесс, прослушивающий порт 12345, подключается ко мне, создавая сокет s, как мне найти порт, который он прослушивает?

sockaddr_in addr;
int len = sizeof(addr);
getpeername(s, (sockaddr*)&addr, &len);
cout << string(inet_ntoa(addr.sin_addr)) << ":" << ntohs(addr.sin_port) << endl;

Не должен ли вывод быть 127.0.0.1:12345? Вместо этого я получаю 127.0.0.1:62305 или какой-то другой произвольный номер порта. Это ошибка с моей стороны, или это должно быть так?

Ответы [ 4 ]

1 голос
/ 17 сентября 2009

Похоже, что у вас есть два процесса, прослушивающие два порта - это два сокета прослушивания, независимых друг от друга. Затем вы создаете третий клиентский сокет в одном из процессов и подключаетесь к другому. Этот третий сокет получает эфемерный порт , назначенный ему стеком TCP (62305 в вашем случае). Таким образом, соединение здесь представлено кортежем {исходный ip, исходный порт, целевой ip, целевой порт} - {127.0.0.1,62305,127.0.0.1,54321}. Это соединение не имеет абсолютно никакого отношения к любым прослушивающим сокетам, которые может иметь процесс соединения. Вы должны явно спроектировать свое приложение для передачи номеров портов между узлами, если вам нужно их знать. Если вы просто хотите узнать, какой процесс имеет какие сокеты, всегда есть lsof .

1 голос
/ 17 сентября 2009

Для уточнения ответа RageZ, getpeername () возвращает порт source и адрес другой стороны вашего сокета. Порт 12345 - это адрес пункта назначения, который вы передали bind (). Как правило, клиенты (например, telnet, nc и т. Д.) Не будут вызывать bind () в своем сокете, поскольку они не хотят прослушивать соединения. Поэтому ОС назначит им произвольный «эфемерный» номер порта.

В общем, нет ничего полезного в том, чтобы знать исходный порт TCP-соединения.

0 голосов
/ 17 сентября 2009

Вы должны получить 127.0.0.1:12345, если s подключен. Вы уверены, что он подключен?

Вам необходимо проверить код возврата getpeername(), чтобы убедиться в отсутствии ошибок.

0 голосов
/ 17 сентября 2009

getpeername дает подробную информацию о клиенте, а не о сервере, поэтому имеет смысл получить какой-нибудь случайный порт.

Вы можете увидеть man page

Приветствия

...