send udp - ICMP error..
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.94] |
|
|
| Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
send udp - ICMP error..
|
Сообщ.
#16
,
|
|
|
|
и да, вот что пишет мистер Стивенс
Цитата 5.3 Does doing a connect() call affect the receive behaviourof the socket? From Richard Stevens ( rstevens@noao.edu): Yes, in two ways. First, only datagrams from your "connected peer" are returned. All others arriving at your port are not delivered to you. But most importantly, a UDP socket must be connected to receive ICMP errors. Pp. 748-749 of "TCP/IP Illustrated, Volume 2" give all the gory details on why this is so. 5.4 How can I read ICMP errors from "connected" UDP sockets? If the target machine discards the message because there is no process reading on the requested port number, it sends an ICMP message to your machine which will cause the next system call on the socket to return ECONNREFUSED. Since delivery of ICMP messages is not guarenteed you may not recieve this notification on the first transaction. Remember that your socket must be "connected" in order to receive the ICMP errors. I've been told that Linux will return them on "unconnected" sockets, but I haven't verfied it. This may cause porting problems if your application isn't ready for it. там английским по белому написано что мои предположения правильные. Утром буду курить бамбук. |
|
Сообщ.
#17
,
|
|
|
|
Цитата nemez @ там английским по белому написано что мои предположения правильные. Написано, но не совсем там, где ты выделил. Я бы больше обратил внимание на это Цитата Remember that your socket must be "connected" in order to receive the ICMP errors. I've been told that Linux will return them on "unconnected" sockets, but I haven't verfied it. This may cause porting problems if your application isn't ready for it. Т.е. тебе нужно вызвать connect() для сокета, т.е. работать с ним как с TCP. Можешь попробовать так, возможно выйдет. Но я бы рекомендовал проверить на всех платформах, особенно в винде. Добавлено И да, там также написано: Цитата nemez @ Since delivery of ICMP messages is not guarenteed you may not recieve this notification on the first transaction. т.е. это тоже не 100% гарантия, что сообщение о дисконнекте к тебе дойдёт |
|
Сообщ.
#18
,
|
|
|
|
ну то что сообщения проходят - это факт.
А во всем остальном надо экспериментировать. Может кто по этим граблям уже походил? А насчет коннекта таки да, обязательно надо попробовать! |
|
Сообщ.
#19
,
|
|
|
|
Цитата nemez @ А насчет коннекта таки да, обязательно надо попробовать! после connect, кстати, нужно работать не через sendto и recvfrom, а через send и recv. Так, на всякий случай. |
|
Сообщ.
#20
,
|
|
|
|
Цитата Теперь посмотрим, что же произойдет, если в UDP-клиенте, например, вместо bind() записать connect()? Во-первых, ядро не будет инициировать "переговорный процесс", т.к. в UDP его нет. Во-вторых, ядро просто запишет в системную область памяти адресные данные удаленного хоста (IP-адрес и номер порта), на которые указывается в параметре вызова connect(), и на этом работа connect() завершится. Такой сокет называется "соединенным" (connected), в то время как по умолчанию для UDP создается "несоединенный" сокет "Соединенный" UDP-сокет налагает некоторые ограничения в его дальнейшем использовании. Вызов функции connect() в случае UDP фактически устанавливает фильтр для входящих дейтаграмм. Как видим, речь здесь идет о клиенте... А какой с него толк, если его убивают kill-9? |
|
Сообщ.
#21
,
|
|
|
|
Oleg2004
на самом деле на udp сокетах не особо есть какое-то понятие серверности и клиентности. Для того чтобы назначить src или dst порты, делаем bind() и connect() |
|
Сообщ.
#22
,
|
|
|
|
nemez
Как то протокольно - да. Но модель клиент-сервер - работает. Сервер всегда висит на recv(). На сервере - обязателен bind() |
|
Сообщ.
#23
,
|
|
|
|
Цитата Сервер всегда висит на recv(). как раз таки на recvfrom() - так мы можем различать клиентов. И в случае чего им ответить. а без sockaddr это нереально. Да и ответить можно с серверного сокета kb,j с sendto, либо через send с предварительным connect. В двух случаях нам нужно знать куда слать. А узнать это можно только через recvfrom. Вот клиенскому сокету как раз таки правильно всегда висеть на rcv - он будет принимать дату только от сервера. А если нам надо сделать сокет, для которого src и dst порты будут фиксированы - в этом случае нужно использовать связку bind() и connect(). И пофиг какой это сокет - клиенский или серверный. Эта тема применяется в ip телефонии очень активно Принимать дату он будет исключительно на порт для которого сделан bind() - если сокет рассматривается как серверный то bind делается на src порт а connect на dst. И все с точностью до наоборот для клиента. Скажем, нам необходимо передавать речевой трафик с порта 22375 на порт 10001. На сервере мы делаем bind на 10001 и connect на 22375. На клиенте мы биндимся на 22375 и коннектимся на 10001. И работаем на сокетах через send и recv - архитектурной разницы между клиентским и серверным сокетом нету кроме их зеркального отображения. |
|
Сообщ.
#24
,
|
|
|
|
Цитата nemez @ как раз таки на recvfrom() Ну это уже тонкости...recv() - здесь в смысле "работает на получение "Цитата nemez @ На сервере мы делаем bind на 10001 и connect на 22375. На клиенте мы биндимся на 22375 и коннектимся на 10001. И работаем на сокетах через send и recv - архитектурной разницы между клиентским и серверным сокетом нету кроме их зеркального отображения. Ну это уже несколько из другой оперы - и другого протокола пользовательского уровня. Ежику понятно, что одно и то же приложение может исполнять когда надо роль клиента, а надо - сервера...только все это надо закодить... |