![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сканирование лок. сети и поиск программы-сервера по ней
Swimmer © (2004-02-13 20:24:00)Ув. Мастера, помогите. Принес я преподавателю сетевую программу. В ini-файлах прог-клиентов указываю IP сервера, все отлично работает, мне лично нравится. Но не преподу! Он требует, чтоб клиенты сами искали сервер по всей локалке, как в программах для администрирования клубов! Как сие можно реализовать? Уж очень нужно. Да, лучше всего подошло бы решение с использованием TClientSocket и TServerSocket.
Polevi (2004-02-17 11:50:00) [1]>Verg © (17.02.04 11:33) [12]
ну будем считать что у нас один интерфейс :)
а вообще можно ручками несколько sendto
Verg (2004-02-17 11:33:00) [2]
> Polevi © (17.02.04 10:00) [11]
> Addr.sin_addr.s_addr := INADDR_BROADCAST;
Вот это немного мутный вопрос.
Если несколько сетевых карт, то куда уйдет такой броадкаст?
BSD-системы делают что - ядро само понимает что ты хочешь отправить всем в сегменте(ах), достает таблицу интерфесов и рассылает в каждую подсеть уже нормальный броадкаст, т.е. на броадкастовые IP адреса всех подсетей (ifaddr_ipv4 | ~ifaddr_subnetmask).
А вот под виндами, тут по-моему, этот номер не пройдет. Пакет отправится на какой-то один сегмент (сетевую карту). На какой?
Я сам толком с этим не разобрался. Почему винды прописывает в маршрутную таблицу путь к INADDR_BROADCAST на какой-то один интерфейс. Главное - я не могу понять почему именно этот она выбирает, а не какой-то другой. Из каких соображений?
Polevi (2004-02-17 10:00:00) [3]поток читает UDP пакеты, пришедшие на порт 5555
код не анализирует результат вызова WSAWaitForMultipleEvents, кому надо тот доделает :)
procedure TT.Execute;
var
Buffer:Pointer;
Len:integer;
evt:THandle;
bytesRecvd:integer;
const
bufLen=512;
begin
GetMem(Buffer,bufLen);
try
try
FSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
FAddr.sin_family := AF_INET;
FAddr.sin_addr.s_addr := INADDR_ANY;
FAddr.sin_port := htons(5555);
if bind(FSocket, @FAddr, SizeOf(FAddr))=SOCKET_ERROR then
RaiseLastWin32Error;
evt:=CreateEvent(nil,false,false,nil);
WSAEventSelect(FSocket,evt,FD_READ);
while not Terminated do
begin
WSAWaitForMultipleEvents(1,@evt,false,INFINITE,false);
Len:=sizeof(FAddr);
ZeroMemory(Buffer,bufLen);
bytesRecvd:=recvfrom(FSocket,Buffer^,bufLen,0,FAddr,Len);
if bytesRecvd=SOCKET_ERROR then
RaiseLastWin32Error;
//буфер содержит данные, чтото с ними делаем...
end;
CloseHandle(evt);
closesocket(FSocket);
except
end;
finally
FreeMem(Buffer);
end;
end;
отправляем в сеть броадкаст пакет по порту 5555
procedure TForm1.Button1Click(Sender: TObject);
var
ASocket:TSocket;
Addr: TSockAddrIn;
Len:integer;
BroadCast:boolean;
begin
BroadCast:=true;
ASocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
setsockopt (ASocket,SOL_SOCKET,SO_BROADCAST,PChar(@BroadCast),sizeof(boolean));
Addr.sin_family := AF_INET;
Addr.sin_addr.s_addr := INADDR_BROADCAST;
Addr.sin_port := htons(5555);
Len:=sizeof(Addr);
if sendto(ASocket,PChar('hello world')^,12,0,Addr,Len)=SOCKET_ERROR then
RaiseLastWin32Error;
closesocket(ASocket);
end;
да и не забыть про WSAStartup
Alex Konshin (2004-02-17 09:50:00) [4]Я это подозревал. Значит, нельзя.
Polevi (2004-02-17 09:25:00) [5]он не умеет
Alex Konshin (2004-02-17 06:42:00) [6]Я с TClientSocket не работаю. Если он умеет создавать UDP сокеты, то можно, если нет, то нет.
dr Tr0jan (2004-02-17 06:21:00) [7]2 Alex Konshin © (14.02.04 05:49) [6]:
А как отправить Broadcast запрос, используя TClientSocket?
Alex Konshin (2004-02-14 05:49:00) [8]Ничего не надо перебирать. Клиент должен послать broadcast запрос, а сервер - просто на него ответить. Вот так клиент и узнает его адрес.
Так мимо шел (2004-02-14 05:02:00) [9]В общих чертах:
порт клиента и сервера одинаковые (иначе никак :) ) отсюда:
1) в диалог сервера с клиентом закладываешь команду, ну допустим
GetStatusMyServer на которую сервер должен ответить StatusServer_Ready
2) в клиенте вкладываешь следующую фичу: перебираешь все станции в сети (на форуме много таких примеров, тема довольно таки избита) определяешь по имени станции ее IP-адрес и посылаешь команду GetStatusMyServer, если на этой станции твой сервер, то он ответит StatusServer_Ready
и т.д. и т.п. :)
(2004-02-13 21:26:00) [10]Удалено модератором
(2004-02-13 21:26:00) [11]Удалено модератором
Swimmer (2004-02-13 21:23:00) [12]Расскажите как...
Dimaz-z (2004-02-13 20:58:00) [13]ClientSocket & ServerSocket тут не подойдут...
используй UDP