Задать вопрос

Можно ли отправить на UDP дейтаграммы прямо через слушающий сокет?

Ситуация следующая WinSocket API, реализация вообще на Delphi 6, при этом меня больше то интересует реализация на уровне Win Socket API, хотя если кто знает применительно к Delphi хуже не будет.
Ситуация следующая. Создан UDP серверный сокет, привязан к адресу ждёт сообщений в отдельной нити.
Приходит UDP сообщение указанному выше серверному сокету. В этот момент я получаю IP и порт отправителя, после чего пробую послать используя слушающий серверный сокет сообщение на IP и порт отправителя только что полученного сообщения, вообще это строчкой:
SendRes:= sendto(FSocket,messageToSend[1],Length(messageToSend),0,SendAddr,SizeOf(SendAddr));//Тут значит следующие параметры указаны:

1) FSocket - тот самый слушающий сокет, который и получил изначальное сообщение
2) messageToSend переменная типа string содержит отправляемое новое сообщение(от сервера клиенту)
3) Length(messageToSend) - длина отправляемого сообщения, то ест переменной messageToSend
4) тут 0 так и было, это не я придумал, это так было в примерах
5) SendAddr содержит адрес и порт кому отправлять
6) длина переменной SendAddr
При попытке отправить как раз в этой строчке и возникает ошибка, поэтому вопрос вообще можно ли так делать.

Я рассуждаю так: раз игры по UDP за NAT работают, значит предположительно сервер шлёт сообщения клиенту на тот же порт с которого они пришли. Или тут дело не в этом?(про NAT написал только чтобы показать как рассуждаю, на самом же деле тестировал на локальном ПК, то есть и ошибка произошла когда и клиент и сервер запущены на одном ПК, и ситуация с разными портами клиента тоже)

Ещё дополнительный вопрос к теме: Почему у меня в клиентской программе, которая отправляет сообщение серверу порт клиента определяется один, а на сервере порт клиента другой? Например на клиентской программе порт клиента - 13574(всегда большие), а на серверной порт клиента к примеру - 1589(то есть примерно такого диапазона)?
  • Вопрос задан
  • 362 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
nikolaevevge
@nikolaevevge Автор вопроса
Частично разобрался.
Касаемо вопроса: можно ли через слушающий серверный сокет отправлять назад сообщение для клиента: да можно, доходит, клиент получает.
Касаемо почему клиентский порт на клиентской программе отличается от клиентского порта в серверной программе - не понял почему, но у меня они отличаются. Причём всё доходит.
Вот скринсшот ситуации:
udp-server-and-client-echo-message.jpg
А ситуация что у меня по sendto не отправлялось сообщение клиенту - нашёл ошибку в коде, оказалось я процедуру использовал по кнопке прямо из класса, а нужно было её вызывать у экземпляра объекта, таким образом получалось что серверный сокет в той процедуре был не инициализирован.

Исходники клиентской и серверной программы на Delphi и прочие детали по ссылке blog.ivru.net/?id=199

__________________________________________
Редактирую ответ, поскольку нашёл причину почему порты отличались:
__________________________________________
Как оказалось в случаи клиентской программы я не использовал ntohs для перестановки старшего и младшего байты порта в переменной адреса, а в случаи серверной программы использовал ntohs. Вот и получились integer числа в одном случаи младший и старший байт шли в одном порядке а в другом в обратном порядке.
Более детально ситуация описана тут https://ru.stackoverflow.com/questions/1137180/win...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
HemulGM
@HemulGM Куратор тега Delphi
Delphi Developer, сис. админ
На клиенте у тебя порт локальный, а снаружи ты видишь порт роутера или другого устройства NAT.
Ip сервера 1.1.1.1 порт 111.
Ip роутера 2.2.2.2 порт 222.
Ip клиента для клиента 127.0.0.1 порт 333.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы