![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как проверить свободен порт или нет? [D6, WinME]
Slava V. © (2002-10-09 11:34:00)Пишу ФТП клиент, при подаче команды PORT генерю случайный порт из диапазона 1024-32768. Как мне проверить этот порт свободен или нет?
MVova (2002-10-10 14:34:00) [1]Да наверное ты прав.
Wonder (2002-10-10 12:51:00) [2]Возникновение конкретно этой ошибки можно легко обойти позволив системе самой выбрать свободный порт, т.е. Wonder © (09.10.02 11:58).
По поводу исключений. А зачем процедуру инициализации сокета вставлять в блок try...except? Ведь ты же сам в ф-ции проверки свободного порта используешь всего-навсего try...finally.
Теперь по алгоритму. Вообрази, что ф-ция проверки порта вернула True. Т.е. порт свободен. Далее происходит то, что я описал, т.е. какое-либо приложение сажает свой сокет на этот порт. Твое приложение пытается занять уже занятый порт - вот тебе и твое "исключение" :) Чем в этом случае использование твоей ф-ции отличается от ее неиспользования?
MVova (2002-10-10 12:20:00) [3]Да это возможно :(
Тогда ищеш новый свободный порт.
Как из вариантов можно конект вставить в try except и там пробовать захватить порт, при ошибке ставить новый порт.
Да вспомнил почему так не получалось:
при схеме try except ты не можеш узнать код ошибки сокета в VCL, а если это не занятый порт а чтото другое не дает занять порт.
И еще одно, может это и не правильно но, я не люблу когда в програме возникают Except если их можно обойти.
Wonder (2002-10-10 12:12:00) [4]А ты не думаешь, что в период сразу послевыполнения строки
CloseSocket(FSocket);
и домомента создания сокета на том свободном порту какое-либо приложение может спокойно создать свой сокет на этом же якобы свободном порту?
MVova (2002-10-10 12:05:00) [5]
> Wonder © (10.10.02 12:00)
Собираешся ты слушать порт X и он занят, а ты запускаеш сокет сервер и он тебя акуратно ругает...
Wonder (2002-10-10 12:00:00) [6]Только вот не понятен практический смысл данной ф-ции.
Ну узнаешь ты, что какой-то порт свободен. И?
MVova (2002-10-10 11:52:00) [7]В принцыпе я не силен в сокетах, но даная схема у меня работает.
>А если ты захочешь одновременно создать несколько сокетов,
>слушающих на разных портах (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
Zz_ (2002-10-10 11:40:00) [8]А если ты захочешь одновременно создать несколько сокетов,
слушающих на разных портах (SO_REUSEADDR), то нужно отлавливать
именно WSAEACCES
MVova (2002-10-10 11:33:00) [9]только
не
if WSAGetLastError = WSAEADDRINUSE then
Result := False
else
Result := True;
а
Result := not(WSAGetLastError = WSAEADDRINUSE);
MVova (2002-10-10 11:28:00) [10]
> Zz_ (10.10.02 11:22)
Чес слово не понял, эта ф-ция у меня в рабочем пакете, все прекрасно работает.
Zz_ (2002-10-10 11:22:00) [11]>MVova © (10.10.02 11:15)
не то
setsockopt(Socket,SOL_SOCKET,SO_REUSEADDR,LPCSTR(&i),sizeof(bool));
там вроде ошибка WSAEACCESS = 10013
MVova (2002-10-10 11:15:00) [12]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;
Wonder (2002-10-09 11:58:00) [13]Бинди с адресом порта 0 - система сам выберет свободный из 1024-5000. Потом его узнаЁшь и лепишь в команду PORT.
Slava V. (2002-10-09 11:41:00) [14]А как-то более гуманно это можно проверить?
Polevi (2002-10-09 11:40:00) [15]если bind вернет ошибку значит занят