Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.12.05;
Скачать: CL | DM;

Вниз

Как проверить свободен порт или нет?   Найти похожие ветки 

 
Slava V.   (2002-10-09 11:34) [0]

Пишу ФТП клиент, при подаче команды PORT генерю случайный порт из диапазона 1024-32768. Как мне проверить этот порт свободен или нет?


 
Polevi ©   (2002-10-09 11:40) [1]

если bind вернет ошибку значит занят


 
Slava V.   (2002-10-09 11:41) [2]

А как-то более гуманно это можно проверить?


 
Wonder ©   (2002-10-09 11:58) [3]

Бинди с адресом порта 0 - система сам выберет свободный из 1024-5000. Потом его узнаЁшь и лепишь в команду PORT.


 
MVova ©   (2002-10-10 11:15) [4]

function IsFreePort(Port : Integer) : Boolean;
var
FSocket : TSocket;
FAddr : TSockAddrIn;
begin
FSocket := Socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
try
FAddr.sin_family := PF_INET;
FAddr.sin_addr.S_addr := INADDR_ANY;
FAddr.sin_port := htons(Port);
Bind(FSocket, FAddr, SizeOf(FAddr));
if WSAGetLastError = WSAEADDRINUSE then
Result := False
else
Result := True;
finally
CloseSocket(FSocket);
end;
end;


 
Zz_   (2002-10-10 11:22) [5]

>MVova © (10.10.02 11:15)
не то
setsockopt(Socket,SOL_SOCKET,SO_REUSEADDR,LPCSTR(&i),sizeof(bool));

там вроде ошибка WSAEACCESS = 10013


 
MVova ©   (2002-10-10 11:28) [6]


> Zz_ (10.10.02 11:22)

Чес слово не понял, эта ф-ция у меня в рабочем пакете, все прекрасно работает.


 
MVova ©   (2002-10-10 11:33) [7]

только
не
if WSAGetLastError = WSAEADDRINUSE then
Result := False
else
Result := True;
а
Result := not(WSAGetLastError = WSAEADDRINUSE);


 
Zz_   (2002-10-10 11:40) [8]

А если ты захочешь одновременно создать несколько сокетов,
слушающих на разных портах (SO_REUSEADDR), то нужно отлавливать
именно WSAEACCES


 
MVova ©   (2002-10-10 11:52) [9]

В принцыпе я не силен в сокетах, но даная схема у меня работает.

>А если ты захочешь одновременно создать несколько сокетов,
>слушающих на разных портах (SO_REUSEADDR)

В смысле несколько сокет серверов на разных портах?

function GetFreePort(PortStart, PortCount : Integer) : Integer;
var
I : Integer;
begin
Result := 0;
for I := PortStart to PortStart + PortCount do
if IsFreePort(I) then
begin
Result := I;
Break;
end;
end;
------------------------------------

i := GetFreePort(10000,10000);
Слушаем Порт i
i := GetFreePort(10000,10000);
Слушаем Порт i


 
Wonder ©   (2002-10-10 12:00) [10]

Только вот не понятен практический смысл данной ф-ции.
Ну узнаешь ты, что какой-то порт свободен. И?


 
MVova ©   (2002-10-10 12:05) [11]


> Wonder © (10.10.02 12:00)

Собираешся ты слушать порт X и он занят, а ты запускаеш сокет сервер и он тебя акуратно ругает...


 
Wonder ©   (2002-10-10 12:12) [12]

А ты не думаешь, что в период сразу после выполнения строки
CloseSocket(FSocket);
и до момента создания сокета на том свободном порту какое-либо приложение может спокойно создать свой сокет на этом же якобы свободном порту?


 
MVova ©   (2002-10-10 12:20) [13]

Да это возможно :(
Тогда ищеш новый свободный порт.

Как из вариантов можно конект вставить в try except и там пробовать захватить порт, при ошибке ставить новый порт.

Да вспомнил почему так не получалось:
при схеме try except ты не можеш узнать код ошибки сокета в VCL, а если это не занятый порт а чтото другое не дает занять порт.

И еще одно, может это и не правильно но, я не люблу когда в програме возникают Except если их можно обойти.


 
Wonder ©   (2002-10-10 12:51) [14]

Возникновение конкретно этой ошибки можно легко обойти позволив системе самой выбрать свободный порт, т.е. Wonder © (09.10.02 11:58).

По поводу исключений. А зачем процедуру инициализации сокета вставлять в блок try...except? Ведь ты же сам в ф-ции проверки свободного порта используешь всего-навсего try...finally.

Теперь по алгоритму. Вообрази, что ф-ция проверки порта вернула True. Т.е. порт свободен. Далее происходит то, что я описал, т.е. какое-либо приложение сажает свой сокет на этот порт. Твое приложение пытается занять уже занятый порт - вот тебе и твое "исключение" :) Чем в этом случае использование твоей ф-ции отличается от ее неиспользования?


 
MVova ©   (2002-10-10 14:34) [15]

Да наверное ты прав.



Страницы: 1 вся ветка

Текущий архив: 2002.12.05;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.011 c
3-14435
NeyroSpace
2002-11-18 10:57
2002.12.05
Как зайти в IBExpert НЕ под SYSDBA?


1-14585
volph7777
2002-11-27 13:25
2002.12.05
ownerdraw listbox


14-14750
Dr. Well
2002-11-14 13:44
2002.12.05
I need help!


1-14608
NorthMan
2002-11-23 14:52
2002.12.05
Опять таймер


1-14521
Kurt
2002-11-26 15:15
2002.12.05
Как рамку вокруг GroupBox-а и Panel выделить определенным цветом