Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

indy: автоматический поиск сервера

20 views
Skip to first unread message

Alexander Grischenko

unread,
Oct 23, 2007, 7:18:40 AM10/23/07
to
Привет, all!

Подскажите, как можно с помощью Indy реализовать следующую фишку. Есть некий
сервер, есть клиенты. Hаходятся они в локальной сети. Клиенты - это некие
устройства, черные ящики с дисплеями, но без клавиатуры (хотя клава может
подключаться для настроек). Хотелось бы сделать так, чтобы при подключении
нового устройстова-клиента он сам бы находил в локалке сервер и подключался к
нему. Сервер отвечает на входящие соединения по порту 5000. Вариант ручной
настройки тоже предусмотрен, но на пожарный случай, если устройство не может
само найти сервер или их более одного. Система должна быть автономной, например,
если сервер ушел в даун (перегрузили или перенесли его функции на другой
компьютер), а потом снова ожил, то клиенты должны автоматом его найти и снова
подключиться.
Есть идея посылать UDP-пакеты для поиска клиентом сервера и сервером для
сообщения о том, что он ожил. Может есть примеры реализации таких вещей?

--
Alexander Grischenko
<gralex(at)ml.lv>

Alexander Grischenko

unread,
Oct 23, 2007, 7:19:10 AM10/23/07
to

Alexander Grischenko

unread,
Oct 23, 2007, 7:24:46 AM10/23/07
to

Del

unread,
Oct 24, 2007, 1:58:08 AM10/24/07
to
Alexander Grischenko пишет:

> Есть идея посылать UDP-пакеты для поиска клиентом сервера и сервером
> для сообщения о том, что он ожил. Может есть примеры реализации таких
> вещей?

Попробуем обойтись без INDY

unit net_stuff;

interface
uses Windows, Messages, SysUtils, Classes, Dialogs, WinTypes, WinProcs, WinSock;
const
WINSOCK_VERSION = $0101;
{==============================================================================}
{== Описание типов ============================================================}
{==============================================================================}
type
PNetResourceArray = ^TNetResourceArray;
TNetResourceArray = array[0..MaxInt div SizeOf(TNetResource) - 1] of
TNetResource;
type SERVER_INFO_100 = record
sv100_platform_id : DWORD;
sv100_name : LPWSTR;
end;
PSERVER_INFO_100 = ^SERVER_INFO_100;
LPSERVER_INFO_100 = ^SERVER_INFO_100;
{==============================================================================}
{== Импортируемые функции =====================================================}
{==============================================================================}
function NetApiBufferFree(Buffer: Pointer): DWORD; stdcall; external
'netapi32.dll';
function NetServerEnum(
servername : LPCWSTR;
level : DWORD;
buf : PSERVER_INFO_100;
prefmaxlen : DWORD;
entriesread : LPDWORD;
totalentries : LPDWORD;
servertype : DWORD;
domain : LPCWSTR;
resume_handle : LPDWORD
): DWORD; stdcall; external 'netapi32.dll';
//------------------------------------------------------------------------------
function EnumWorkstations(Server, Domain : string) : TStringList;
function GetIPAddress(name: string): string;

implementation
//-- Получение IP по имени -----------------------------------------------------
function GetIPAddress(name: string): string;
var
WSAData: TWSAData;
p: PHostEnt;
begin
WSAStartup(WINSOCK_VERSION, WSAData);
p := GetHostByName(PChar(name));
Result := inet_ntoa(PInAddr(p.h_addr_list^)^);
WSACleanup;
end;
//-- Список находящихся в сети машин -------------------------------------------
function EnumWorkstations(Server, Domain : string) : TStringList;
var Buffer, tmpBuffer : Pointer;
prefmaxlen : Integer;
resume_handle : DWORD;
entriesread : DWORD;
totalentries : DWORD;
I, Size : Integer;
CompName : string;
PSrvr, Dom : PWideChar;
Begin
Result := TStringList.Create;
Try
Size := Length(Server);
if Size > 0 then begin
GetMem(PSrvr, Size*SizeOf(WideChar)+1);
StringToWideChar(Server, PSrvr, Size+1);
end else PSrvr := nil;

Size := Length(Domain);
if Size > 0 then begin
GetMem(Dom, Size*SizeOf(WideChar)+1);
StringToWideChar(Domain, Dom, Size+1);
end else Dom := nil;

prefmaxlen := -1;
entriesread := 0;
totalentries := 0;
resume_handle := 0;
if NetServerEnum(PSrvr, 100, @Buffer, prefmaxlen, @entriesread,
@totalentries, 1, Dom, @resume_handle) = S_OK
then begin
tmpBuffer := Buffer;
for I := 0 To totalentries - 1 do begin
CompName := PSERVER_INFO_100(tmpBuffer).sv100_name;
resume_handle := 0;
Result.Add(CompName);
tmpBuffer := Pointer(DWORD(tmpBuffer) + SizeOf(SERVER_INFO_100));
end;
end;
finally
NetApiBufferFree(Buffer);
end;
FreeMem(PSrvr);
end;

end.

Таким образом мы получим список машин в сети. А далее любым способом
проверяем - открыт ли нужный порт и идет ли из него правльный ответ. Hапример
- с помощью TClientSocket.

--
Шмырев А. А.

Alexander Grischenko

unread,
Oct 24, 2007, 4:26:52 AM10/24/07
to
ФиDel пишет:

> Alexander Grischenko пишет:
>
>> Есть идея посылать UDP-пакеты для поиска клиентом сервера и сервером
>> для сообщения о том, что он ожил. Может есть примеры реализации таких
>> вещей?
>
> Попробуем обойтись без INDY
>
> unit net_stuff;
[Skipped]

>
> Таким образом мы получим список машин в сети. А далее любым способом
> проверяем - открыт ли нужный порт и идет ли из него правльный ответ.
> Hапример - с помощью TClientSocket.
>

Хмм... пример интересный, спасибо :) , но есть одна загвоздка. Дело в том, что
девайсы работают под управлением Windows XP Embedded, и оттуда исключены все
лишние модули, в том числе и MS Network, т.е. сервисы клиента и сервера там не
работают, только чистый TCP\IP. Hу и, соответсвенно, работают только те сетевые
сервисы, которые я сам запустил, в данном случае только моя прога, которая
должна передавать серверу данные, собираемые устройством. Сам сервер работает на
обычном компе. Сомневаюсь, что предложенный способ поиска машин будет работать в
данном случае...

--
Alexander Grischenko
<gralex(at)ml.lv>

Serj Silantiev

unread,
Oct 26, 2007, 12:06:22 AM10/26/07
to
Пpивет Alexander! Как оно ничего живется ?

24 окт 07 Alexander Grischenko пишет для Del

AG> Хмм... пpимеp интеpесный, спасибо :) , но есть одна загвоздка. Дело в том,
AG> что девайсы pаботают под упpавлением Windows XP Embedded, и оттуда
AG> исключены все лишние модули, в том числе и MS Network, т.е. сеpвисы
AG> клиента и сеpвеpа там не pаботают, только чистый TCP\IP.

Может тебе в стоpону бpодкастов поглядеть? Почитай о pеализации пpотокола
SAP (service advertisment protocol). А заодно и SLP (service location
protocol).

Общая идея такова: в пеpвом сеpвеp пеpиодически посылает шиpоковещательные
сообщения - мол я такой-то, с такими-то возможностями, клиенты слушают;
во втоpом случае клиент посылает шиpоковещательные запpосы - мол кто тут
занимается тем-то и тем-то, а сеpвеp слушает и откликается.

Так pаботают многие сеpвисы, dhcp напpимеp.

Реализовать, imho, можно обычными сокетами.

Hу пока.
--
В ногах пpавды нет! Она где-то между...

0 new messages