Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.007 c
1-14680
chuvack
2002-11-25 16:52
2002.12.05
Как в Delphi можно импортировать документ Word


3-14383
sosv
2002-11-19 16:17
2002.12.05
Клиент - сервер


3-14447
Sergioly
2002-11-15 10:28
2002.12.05
БД в локалке!


14-14741
Мазут Береговой
2002-11-13 20:26
2002.12.05
Где можно скачать MS SQL Server 2000?


14-14792
dkDimon
2002-11-14 23:23
2002.12.05
Иваново





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский