По каким законам выбирается случайный порт при TCP/IP соединении?18.03.08 11:59 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 18.03.08 12:01 Количество правок: 2
Активные подключения
Имя Локальный адрес Внешний адрес Состояние
TCP xxx.xxx.xxx.xxx:1477 yyy.yyy.yyy.yyy:5190 ESTABLISHED
--- Видим, что система по просьбе приложения создать соединение на сервер ICQ на порт 5190 по каким-то одной ей ведомым законам воткнула обратную "слушалку" на порт 1477. Вопрос: существует ли вероятность, что создавая службу, которая "слушает" на портах, больше 1000, столкнуться с такой ситуацией, что этот порт будет совершенно случайно занят на обслуживание какого-нибудь левого соединения "наружу"? Почему никто из серверописателей "не боится" такой ситуации? Вероятность, в общем-то, достаточно большая для компьютинга.
Извините, что вопрос глупый, но типо "не юзай большие номера" отвечать, конечно, можно, но не нужно.
И заранее всем спасибо за ответы, конечно. -))
> Активные подключения
>
> Имя Локальный адрес Внешний адрес
> Состояние
> TCP xxx.xxx.xxx.xxx:1477 yyy.yyy.yyy.yyy:5190
> ESTABLISHED
>
--- > Видим, что система по просьбе приложения создать соединение > на сервер ICQ на порт 5190 по каким-то одной ей ведомым > законам воткнула обратную "слушалку" на порт 1477.
1477 в данном случае не открыт для входящих соединений. Сокет определяется четыремя параметрами, а не двумя. Я думаю, можешь спокойно в этой ситуации открывать порт 1477 для входящих соединений.
Во я тупой... Спасибо за науку! :)18.03.08 13:16 Автор: HandleX <Александр М.> Статус: The Elderman
Оопс... Не даёт забиндиться на занятый локальный порт...18.03.08 14:08 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 18.03.08 14:17 Количество правок: 4
E:\>netstat -n
Активные подключения
Имя Локальный адрес Внешний адрес Состояние
TCP xxx.xxx.xxx.xxx:1486 64.12.24.244:5190 ESTABLISHED
--- Выполняю вот такое:
lib := WS2_32Library default.
s := lib socket: AF_INET type: SOCK_STREAM protocol: 0.
s asSignedInteger = SOCKET_ERROR
ifTrue: [^SocketError signal].
si := SOCKADDR_IN new.
si sin_family: AF_INET.
si sin_addr s_addr: (InternetAddress host: 'xxx.xxx.xxx.xxx') asParameter.
si sin_port: (lib htons: 1486).
(lib bind: s name: si yourAddress namelen: si byteSize) = SOCKET_ERROR
ifTrue: [^SocketError signal].
--- Причём WSAGetLastError возвращает "Операция успешно завершена", гы-гы-гы. Но это ложь, поскольку bind возвращает -1.
При попытке забиндится на любой другой незанятый порт всё проходит нормально.
О как...18.03.08 14:39 Автор: Ustin <Ustin> Статус: Elderman Отредактировано 18.03.08 14:51 Количество правок: 4
Не помню откуда, на задворках сознания вертится:
если добавить в C:\WINDOWS\system32\drivers\etc\services строку с crlf на конце
mysvc 1477/tcp mysvc
---,
то 1477 порт не будет использоваться для исходящих TCP соединений.
Но это необходимо проверить
А также чем раньше поднять слушающий сокет, тем больше вероятности, что он займёт свой порт до момента его занятия чем-либо ещё.
:( Засада, мне казалось всегда, что в подобной ситуации исходящий коннект разрывается с GetLastError=10054 или 10048, буду знать... btw, а что говорит GetLastError?
Да, я неправильно вытаскивал WSAGetLastError, реальная ошибка 10048.18.03.08 15:06 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 18.03.08 15:06 Количество правок: 1
> Не помню откуда, на задворках сознания вертится: > если добавить в C:\WINDOWS\system32\drivers\etc\services > строку с crlf на конце > ==skipped== > то 1477 порт не будет использоваться для исходящих TCP > соединений. > Но это необходимо проверить Не представляю себе как — после перезагрузки венда выберет скорее всего другой порт... Надо порыть доки M$... Ну это не горит, как-нить попозже... А так да, ценная информация, если верная.
> А также чем раньше поднять слушающий сокет, тем больше > вероятности, что он займёт свой порт до момента его занятия > чем-либо ещё. Это понятно.
> :( Засада, мне казалось всегда, что в подобной ситуации > исходящий коннект разрывается с GetLastError=10054 или > 10048, буду знать... btw, а что говорит GetLastError? Subj. Вытаскивал WSAGetLastError из другого потока.
Проверить можно так:18.03.08 15:23 Автор: Ustin <Ustin> Статус: Elderman Отредактировано 18.03.08 15:27 Количество правок: 1
- добавить запись в services
- перегрузить Windows (по косвенным признакам - поверхностный поиск в инете - файл читается 1 раз при загрузке)
- поднять тестовый сервак, заделать к нему кучу коннектов и набрать статистику по номерам исходящих портов
В дальнейшем, если проверка таки пройдёт, при установке клиента установщиком добавлять указанную запись, как это делают некоторые interbase-based программы (типа http://www.dnop.sds.cn.ua/cp2000/doc/cp2000-adm-setup.shtml)
Проверил - работает! (не прошло и года :) )03.12.08 21:23 Автор: Ustin <Ustin> Статус: Elderman
Столкнулся с подобной задачей - много исходящих коннектов + статистика по исходящим портам.
Если добавить запись C:\WINDOWS\system32\drivers\etc\services вида
mysvc 3333/tcp
и перегрузиться, то после выбор идёт примерно так:
Сокеты создаются единообразно. А потом, чтобы "слушать", надо сделать привязку к порту функцией bind.18.03.08 15:10 Автор: HandleX <Александр М.> Статус: The Elderman