sin_port возвращен в getaddrinfo неправильно - PullRequest
1 голос
/ 26 сентября 2011

Я пишу программу сервер-клиент, и на сервере я использую getaddrinfo и getsockname на сервере, чтобы получить информацию о локальном IP-адресе и локально связанном номере порта. Используя эту информацию, я запускаю свою клиентскую программу и использую getaddrinfo, а затем просто распечатываю возвращенные значения в структуре данных servinfo: getaddrinfo (argc [1], argc [2], & hints, & servinfo); >> Имя хоста сервера и номер порта сервера передаются через командную строку.

Но я замечаю, что sin_port в servinfo - это не тот порт, который я передаю через командную строку. 1) Возвращает ли этот getaddrinfo номер порта, используемый клиентом в качестве номера порта источника? 2) Мой вызов подключения после вызовов getaddrinfo и сокета завершился неудачей. Я не знаю почему. Как мне отладить его?

Мой фрагмент кода клиента:

memset(&hints, 0 ,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags =  AI_CANONNAME | AI_NUMERICSERV;
getaddrinfo(argc[1], argc[2], &hints, &servinfo);

for (p = servinfo till p!=NULL)
    sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)
    connect(sockfd, p->ai_addr, p->ai_addrlen) >>>>> Connect not going through.

Я запускаю свою клиентскую программу следующим образом: ./a.out myservername 18844

Спасибо!

1 Ответ

4 голосов
/ 26 сентября 2011

Новый ответ: Вы вызываете вашу программу только с одним аргументом, поэтому argv[1] содержит "18844", а argv[2] - нулевой указатель. Это попытается подключиться к хосту с числовым IP-адресом 18844 и неуказанным номером порта (который в итоге будет равен 0 и завершится ошибкой).

Старый ответ: (актуально, но не ваша проблема) sin_port и вся структура sockaddr_in находится в порядке сетевых байтов . Вам нужно будет преобразовать порт с помощью ntohl, чтобы использовать его в качестве числа, но лучше не трогать внутренние структуры sockaddr структур. Вместо этого используйте getnameinfo с NI_NUMERICHOST и NI_NUMERICSERV, чтобы вернуть адрес обратно в строковую числовую форму, а затем strtol, чтобы прочитать номер порта («service») в целое число. Это работает даже для семейств сетевых адресов / протоколов не-IPv4 (например, IPv6) и не требует дополнительного кода для поддержки новых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...