Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
ВнизПоиск серверов в LAN Найти похожие ветки
← →
seregin2 (2004-03-01 08:07) [0]Здравствуйте, Мастера! С наступлением весны!
Как реализовать средствами Delphi (TClientSocket и TServerSocket) поиск серверов, аналогичный тому, как Quake ищет запущенные сервера мультиплееры. Можно, конечно, сканировать диапазон IP-адресов, но это медленно. Или Quake так и делает?
← →
seregin2 (2004-03-01 08:59) [1]а как-нибудь использовать широковещательные запросы можно?
← →
just me (2004-03-01 13:18) [2]Посмотри в MSDN функцию NetServerEnum - может решит твою проблему более просто
← →
BiN © (2004-03-01 13:18) [3]Можно!
← →
Verg © (2004-03-01 13:27) [4]
> Можно, конечно, сканировать диапазон IP-адресов, но это
> медленно.
Если речь идет в общем случае о TCP/IP серверах, то сканирование - это универсальное решение.
Только TClientSocket в данном случае использовать будет нерационально.
Для поиска сервер лучше использовать WinSock API сокеты в неблокирующем режиме. Время поиска сервера, если он вообще есть, будет ~равно времени одного соединения.
http://delphimaster.net/view/6-1076919117/
← →
TButton © (2004-03-01 21:56) [5]можно, как вариант, получить список компов в сети и про сканировать их.
← →
Verg © (2004-03-01 22:45) [6]Мдя.
Сам сейчас посмотрел еще раз исходник того сканера. Надо сказать есть масса претензий. Если автор слышит, то предлагаю его заменить на:function FindServer( const Network : string;
const NetMask : string;
Port : word;
TimeOut : integer) : string;
var
Addr:TSockAddr;
Fd : PFdSet;
k, i: u_long;
TmVal:TTimeVal;
StartAddr,
FinishAddr,
Mask : u_long;
SetSize : integer;
S : TSocket;
begin
Result := "";
StartAddr := ntohl(inet_addr(pchar(Network)));
Mask := ntohl(inet_addr(pchar(NetMask)));
if Mask <> u_long($FFFFFFFF) then
begin
StartAddr := (StartAddr and Mask) + 1;
FinishAddr := (StartAddr or not Mask) - 1;
end else
FinishAddr := StartAddr;
SetSize := (FinishAddr - StartAddr) + 1;
if SetSize <= 0 then
exit;
TmVal.tv_sec:=TimeOut;
TmVal.tv_usec:=0;
GetMem(Fd, SetSize*sizeof(Fd^.fd_array[0])+sizeof(Fd^.fd_count));
try
FD_ZERO(Fd^);
ZeroMemory(@Addr, sizeof(Addr));
Addr.sin_family:=AF_INET;
Addr.sin_port:=htons(Port);
k:=1;
For i:=StartAddr to FinishAddr do
begin
Addr.sin_addr.S_addr:=htonl(i);
S := socket(AF_INET, SOCK_STREAM, 0);
if (S <> INVALID_SOCKET) then
begin
if (ioctlsocket(S, FIONBIO, k) = SOCKET_ERROR)
or ( (connect(S, Addr, SizeOf(Addr)) = SOCKET_ERROR)
and (WSAGetLastError <> WSAEWOULDBLOCK)
) then
begin
closesocket( S );
end else
begin
FD.fd_array[FD^.fd_count] := S;
Inc(FD^.fd_count);
end;
end;
end;
if Fd^.fd_count = 0 then
exit;
select(FD^.fd_count, nil, Fd, nil, @TmVal);
For K := 0 to Fd^.fd_count-1 do
begin
if (Result="")
and FD_ISSET( FD^.fd_array[K], Fd^ ) then
begin
I := sizeof(Addr);
if getpeername( FD^.fd_array[K], Addr, I ) <> SOCKET_ERROR then
Result := inet_ntoa(Addr.sin_addr);
end;
closesocket(FD^.fd_array[K]);
end;
finally
FreeMem(Fd);
end;
end;
Главная фишка - FD_SETSIZE. Как его переопределить-то? Это ж нам не C...
А то, ведь, только первые 64-ре адреса проверяться будут
Возражения?
← →
ser_ega (2004-03-02 00:19) [7]>>>> tButton можно, как вариант, получить список компов в сети и про сканировать их.
А примерчик можно как получить список компов в сети?
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.04.25;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.037 c