Могут ли сервер и клиент инициировать связь и отправлять команды через один и тот же порт? - PullRequest
1 голос
/ 05 мая 2011

У меня есть сервер и клиентское приложение, мой сервер прослушивает порт 10015 и клиент, который отправляет команды на этот порт.В настоящее время оба работают на одной машине, но в будущем цель будет работать на разных машинах.У меня сейчас работает эта часть.

Что мне нужно сделать дальше, так это чтобы мой сервер отправлял команды и моему клиенту.Поэтому я подумал, что могу просто повторно использовать свой код со своего сервера в моем клиенте для прослушивания порта.

Но я не уверен, что это лучший способ сделать это.Предложения?

Когда я впервые попробовал это, я сначала запустил свое клиентское приложение, и оно отправило команду себе.Моему серверному приложению не удалось привязаться к порту (я полагаю, что вы можете иметь только один процесс, прослушивающий данный порт?)

Вопрос 1) Как сервер может отправлять команды клиенту?Нужно ли создавать сервер -> связь с клиентом на порту 10015 и клиент ---> сервер на другом порту, например 10016?

Вопрос 2) Когда я отправляю команду с клиента -> серверс send (), каков наилучший способ получить ACK для этой конкретной команды?Если мне не нужно отправлять какие-либо данные назад, есть ли способ просто автоматически получать ACK при получении пакета сервером?

В настоящее время я делаю это для каждой команды, которую я хочу отправить:

create socket()
conenct() to socket
send() packet
then call recv() to receive any data 
then shutdown() connection
and closesocket() at end

не уверен, есть ли лучший способ сделать это?Я ожидаю посылать где-то от 1 до 10 команд в секунду, когда мое приложение занято.

спасибо, я новичок в этом сетевом приложении, поэтому любая помощь очень ценится.

Редактировать после прочтения некоторых комментариев :
Я использую протокол TCP.Когда я сказал ACK, я имел в виду, что я просто хотел получить от другого приложения подтверждение, что команда была получена и обработана без ошибок

Ответы [ 4 ]

6 голосов
/ 05 мая 2011

Обычно это делается следующим образом:

  1. «Сервер» привязывает сокет к указанному порту - похоже, для вас это будет 10015.
  2. «Клиент» использует эфемерный порт для своих исходящих передач
  3. Если сервер должен ответить клиенту, он отправляет сообщение от своего связанного порта (10015) источникупорт сообщения # 2, эфемерный порт.

На сервере:

Если вы используете UDP, вы можете просто скопировать структуру sockaddr, которая была задана во время recvfrom (), вструктура sockaddr, которую вы передаете sendto ().

Если вы используете TCP, дескриптор файла сокета, возвращаемый accept (), может использоваться в send () для отправки трафика ответа клиенту.

Мой любимый справочник по сокетам C - бесплатный и доступный онлайн Руководство Биджа по сетевому программированию .

0 голосов
/ 06 мая 2011

Вы правы в том, что два приложения не могут одновременно прослушивать один и тот же порт и один и тот же адрес 1 .Если вы хотите, чтобы у вашего клиента был собственный сокет прослушивания, он должен использовать другой номер порта - вы можете указать 10015 для сервера и 10016 для клиента.

Однако - вы, скорее всего, не нужно, чтобы у клиента был свой собственный сокет прослушивания.TCP-соединения полнодуплексные - ваш сервер может просто отправлять запросы клиенту обратно по тому же соединению, которое клиент использует для отправки запросов на сервер, если это соединение все еще открыто.

Что касается вопроса2, лучший и единственный способ получить полезный ACK - это заставить ваше приложение отправлять его самостоятельно - обычно, после того, как оно выполнит команду.

Что касается вашего текущего способа отправки команды, где вы настраиваете иразрывать новое соединение для каждой команды, это крайне неэффективно (и также не позволяет использовать то же соединение, что и обратный канал от сервера к клиенту).Вместо этого вы должны держать соединение открытым и использовать его для отправки нескольких команд.


1.На самом деле, это не совсем так - они могут, но каждое входящее соединение может быть принято только одним из них.Это не то, что вы хотите.
0 голосов
/ 06 мая 2011

Они могут прослушивать один и тот же порт, если они находятся на разных хостах.

0 голосов
/ 05 мая 2011

Ваш вопрос подразумевает, что вы используете UDP.Для этого клиент должен прослушивать порт (вместо двусторонней связи в сокете в TCP).

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

Ответ на вопрос 2: вы используете UDP.Вы должны явно отправить что-то обратно.Вы должны использовать recvfrom() на сервере;информация о том, куда отправлять подтверждение, хранится в struct sockaddr *src_addr, который вы передаете.

Редактируйте после перечитывания: Если вы не пытаетесь использовать UDP ... выпросто подключитесь к серверу с клиентом и общайтесь туда и обратно через сокет.Ваш клиент ничего не слушает.Учебное пособие здесь должно помочь.

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