Определите номер порта C ++ Socket - PullRequest
1 голос
/ 23 июля 2010

Хорошо, я могу создать сокет и отправить сообщение на удаленный компьютер (кстати, UDP). Моя проблема в том, что мне нужно знать, на какой порт я отправил сообщение. Удаленный компьютер будет отвечать на тот же порт, с которого я отправил. Сейчас кажется, что он выбирает случайные высокие порты, например 46555. Есть ли способ указать, к какому порту он подключен, или есть какой-то способ узнать, какой это номер порта?

Спасибо.

Ответы [ 8 ]

4 голосов
/ 23 июля 2010

Хотя можно выбрать определенный исходящий порт, это обычно не так, как обычно.

Обычно клиент выбирает случайный порт с высоким номером (как он это делает), а затемСервер определит , какой порт используется клиентом, и ответит на этот порт.Используя сокеты POSIX (Berkeley), сервер получит эту информацию, используя функцию recvfrom, а не функцию recv.Функция recvfrom принимает два дополнительных аргумента, которые она будет заполнять адресом, с которого был получен пакет, включая номер порта.

2 голосов
/ 23 июля 2010

Короткий ответ на ваш вопрос - «bind ()», предполагая, что интерфейс является BSD-socket-ish.

Более длинный ответ

bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))

где fd - файловый дескриптор сокета. Но подождите, спросите вы, что это за «addr» и почему он является указателем на struct sockaddr?

В вашем случае адрес равен

struct sockaddr_in addr;

Которая представляет собой структуру sockaddr в Интернете (указатель на которую можно привести к базовой структуре sockaddr). Перед вызовом bind вам нужно инициализировать адрес:

addr.sin_family = AF_INET;
addr.sin_port = <your chosen port number here!>;
addr.sin_addr = INADDR_ANY;

После вызова bind сокет будет привязан к выбранному вами порту, а не к случайному, и вы сможете отправлять и получать UDP-сообщения на этом порту.

1 голос
/ 23 июля 2010

Когда вы отправляете сообщение с исходного компьютера, вы отправляете его на определенный IP-адрес и ПОРТ.
На удаленном компьютере вам нужно открыть сокет и связать сокет для прослушивания определенного порта.

В любом случае вы указываете порт на обеих машинах (с обычными API-интерфейсами). Сокет на удаленном компьютере прослушивает определенный порт, который вы можете определить.

В beej's guide

содержится много информации.
0 голосов
/ 18 августа 2018

Один из способов исправить порт будет использовать bind(), с этим вы можете отправить на определенный порт на клиенте.Обратите внимание, вы должны быть осторожны, чтобы не использовать стандартные порты.Эта ссылка поможет вам с подробностями http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-en-4/ch-ports.html

Вы можете bind, а затем отправлять и получать ваши пакеты.

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = <required port number>;
addr.sin_addr = INADDR_ANY;

Руководство Биджа - хорошее место, чтобы легко понятьпрограммирования сокетов.https://beej.us/guide/bgnet/html/single/bgnet.html#bind

0 голосов
/ 18 августа 2018

Вот один из способов определения номера порта локального сокета UDP на стороне клиента:

unsigned short local_port;   // the port number we're interested in
struct sockaddr_in sin;
int addrlen = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = 0;  // let the system choose a port number

sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);      // create the socket
bind(sd, (struct sockaddr *)&sin, sizeof(sin));     // assign a port number
getsockname(sd, (struct sockaddr *)&sin, &addrlen); // read binding

local_port = ntohs(sin.sin_port);  // get the port number
0 голосов
/ 23 июля 2010

Рассмотрим подключенных UDP-сокетов - вы получите лучшую производительность и отчеты об ошибках ICMP.

0 голосов
/ 23 июля 2010

В предположении реализации на основе POSIX функции getsockname() и getpeername() работают, по крайней мере, для потоковых сокетов.Функции recvfrom() и sendto() позволяют получать и использовать информацию для сокетов UDP.

Если вы работаете с Windows, эти функции, вероятно, существуют(возможно, с префиксом подчеркивания), но есть и нативные альтернативы, при которых поиск в MSDN будет появляться.

0 голосов
/ 23 июля 2010

Вы должны быть в состоянии установить порт, который вы вызываете при инициализации сокета.Я хотел бы быть менее расплывчатым, но это зависит от того, какую реализацию сокетов вы используете.Например ( из .NET Framework ):

public:
void Bind(
    EndPoint^ localEP
)

Используется с сопутствующим классом IPEndpoint,

public:
IPEndPoint(
    IPAddress^ address, 
    int port
)

Позволит вам установить привязку вашего сокетав любую локальную конечную точку, которую вы хотите.При желании вы можете установить порт на ноль, чтобы он был автоматически назначен вам.Существует также возможность установить IPAddress на INADDR_ANY, что не рекомендуется .

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