Обзор имен компьютеров в сети
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
-
- Ветеран
- Сообщения: 333
- Зарегистрирован: 21 Сентябрь 2005, 11:05
- Откуда: Нижний Новгород
- Контактная информация:
Обзор имен компьютеров в сети
А кто-нибудь знает функцию (или может несколько функций) для обзора имен компьютеров в сети.
Пробую встроить в программу "Чат" через сокеты, и хотелось бы автоматически искать по сети тех, кто сейчас находится в программе...
Пробую встроить в программу "Чат" через сокеты, и хотелось бы автоматически искать по сети тех, кто сейчас находится в программе...
-
- Ветеран движения
- Сообщения: 78
- Зарегистрирован: 04 Август 2005, 9:35
- Контактная информация:
- StillZero
- Ветеран
- Сообщения: 458
- Зарегистрирован: 06 Июль 2005, 2:17
- Откуда: Хабаровск
- Поблагодарили: 1 раз
- Контактная информация:
Вадим, вообщем-то, показал пример обзора компьютеров в сети. Хотя, по сути, это для организации красивого выбора имени компа, можно и руками набрать там \\MyCompName.
IMHO хороший подход: есть список компов, на которых стоит стоит прога, а запущена ли на них прога уже опрашивать потом. Т.е. не делать BROADCAST по всей сети, а зная имена компов и соответственно их адреса, просто опрашивать их командами по TCP типо "ONLINE?" в ответку "ONLINE!" или ошибка.
Как сделать BROADCAST можно посмотреть здесь (делается это по UDP): http://www.clarionlife.net/cgi-bin//bl_ ... senger.zip
Вообще, можно сделать и без использования всяких API: общий файл, каждому компу своя запись, зашел в прогу: выставил байтик, вышел: снял, и периодически должа прога снимать/выставлять активность (если юзер вышел по "reset"-например). Ну и кнопочка refresh должна быть, которая сбрасывает у всех байтик.
IMHO хороший подход: есть список компов, на которых стоит стоит прога, а запущена ли на них прога уже опрашивать потом. Т.е. не делать BROADCAST по всей сети, а зная имена компов и соответственно их адреса, просто опрашивать их командами по TCP типо "ONLINE?" в ответку "ONLINE!" или ошибка.
Как сделать BROADCAST можно посмотреть здесь (делается это по UDP): http://www.clarionlife.net/cgi-bin//bl_ ... senger.zip
Вообще, можно сделать и без использования всяких API: общий файл, каждому компу своя запись, зашел в прогу: выставил байтик, вышел: снял, и периодически должа прога снимать/выставлять активность (если юзер вышел по "reset"-например). Ну и кнопочка refresh должна быть, которая сбрасывает у всех байтик.
-
- Ветеран
- Сообщения: 333
- Зарегистрирован: 21 Сентябрь 2005, 11:05
- Откуда: Нижний Новгород
- Контактная информация:
По ссылке http://msdn.microsoft.com/library/defau ... ources.asp, приведенной выше, пример функции для обзора ресурсов сети:
Попробовал реализовать на Clarion, нужно получать имена компов для опроса запущена прога или нет. Использовать BROADCAST, реализованный в Messenger, не хочу. Гляньте, у кого есть время, целесообразен ли такой вариант и будет ли поддерживаться на разных вариантах настройки сети. У меня одна рабочая группа и порядка 20 машин, все ок.
Код на Clarion:
PS: Динамически создать массив структур NETRESOURCE не получилось, поэтому использую размерность 100
Код: Выделить всё
BOOL WINAPI EnumerateFunc(HWND hwnd,
HDC hdc,
LPNETRESOURCE lpnr)
{
DWORD dwResult, dwResultEnum;
HANDLE hEnum;
DWORD cbBuffer = 16384; // 16K is a good size
DWORD cEntries = -1; // enumerate all possible entries
LPNETRESOURCE lpnrLocal; // pointer to enumerated structures
DWORD i;
//
// Call the WNetOpenEnum function to begin the enumeration.
//
dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources
RESOURCETYPE_ANY, // all resources
0, // enumerate all resources
lpnr, // NULL first time the function is called
&hEnum); // handle to the resource
if (dwResult != NO_ERROR)
{
//
// Process errors with an application-defined error handler.
//
NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum");
return FALSE;
}
//
// Call the GlobalAlloc function to allocate resources.
//
lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);
if (lpnrLocal == NULL)
return FALSE;
do
{
//
// Initialize the buffer.
//
ZeroMemory(lpnrLocal, cbBuffer);
//
// Call the WNetEnumResource function to continue
// the enumeration.
//
dwResultEnum = WNetEnumResource(hEnum, // resource handle
&cEntries, // defined locally as -1
lpnrLocal, // LPNETRESOURCE
&cbBuffer); // buffer size
//
// If the call succeeds, loop through the structures.
//
if (dwResultEnum == NO_ERROR)
{
for(i = 0; i < cEntries; i++)
{
// Call an application-defined function to
// display the contents of the NETRESOURCE structures.
//
DisplayStruct(hdc, &lpnrLocal[i]);
// If the NETRESOURCE structure represents a container resource,
// call the EnumerateFunc function recursively.
if(RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage
& RESOURCEUSAGE_CONTAINER))
if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i]))
TextOut(hdc, 10, 10, "EnumerateFunc returned FALSE.", 29);
}
}
// Process errors.
//
else if (dwResultEnum != ERROR_NO_MORE_ITEMS)
{
NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource");
break;
}
}
//
// End do.
//
while(dwResultEnum != ERROR_NO_MORE_ITEMS);
//
// Call the GlobalFree function to free the memory.
//
GlobalFree((HGLOBAL)lpnrLocal);
//
// Call WNetCloseEnum to end the enumeration.
//
dwResult = WNetCloseEnum(hEnum);
if(dwResult != NO_ERROR)
{
//
// Process errors.
//
NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");
return FALSE;
}
return TRUE;
}
Код на Clarion:
Код: Выделить всё
ERROR_NO_MORE_ITEMS EQUATE(259)
RESOURCE_CONNECTED EQUATE(1)
RESOURCE_GLOBALNET EQUATE(2)
RESOURCE_REMEMBERED EQUATE(3)
RESOURCETYPE_ANY EQUATE(0)
RESOURCETYPE_DISK EQUATE(1)
RESOURCETYPE_PRINT EQUATE(2)
RESOURCEDISPLAYTYPE_GENERIC EQUATE(0)
RESOURCEDISPLAYTYPE_DOMAIN EQUATE(1)
RESOURCEDISPLAYTYPE_SERVER EQUATE(2)
RESOURCEDISPLAYTYPE_SHARE EQUATE(3)
RESOURCEUSAGE_CONTAINER EQUATE(2)
NETRESOURCE GROUP,TYPE
dwScope ULONG
dwType ULONG
dwDisplayType ULONG
dwUsage ULONG
lpLocalName LONG
lpRemoteName LONG
lpComment LONG
lpProvider LONG
END
MODULE('Mpr.lib')
WNetOpenEnum(ULONG,ULONG,ULONG,LONG,HANDLE),ULONG,PASCAL,NAME('WNetOpenEnumA'),DLL(dll_mode)
WNetCloseEnum(HANDLE),ULONG,PASCAL,NAME('WNetCloseEnum'),DLL(dll_mode)
WNetEnumResource(HANDLE,*ULONG,LONG,*ULONG),ULONG,PASCAL,NAME('WNetEnumResourceA'),DLL(dll_mode)
END
GetNetRes_ procedure(*NETRESOURCE lpnr)
lpnr1 group(NETRESOURCE),DIM(100)
end
lpnr2 group(NETRESOURCE)
end
hEnum long
cEntries ulong(-1)
cEntries_ ulong
cbBuffer ulong(105600)
nResult long
I long
strname cstring(260)
loc:error_ string(500)
code
!stop(size(lpnr1))
loc:error_=''
nResult = WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0,address(lpnr),address(hEnum))
if nResult = 0
clear(lpnr1)
nResult = WNetEnumResource(hEnum,cEntries,address(lpnr1),cbBuffer)
if nResult = 0
if cEntries<=200
cEntries_ = cEntries
else
cEntries_ = 200
end
loop I=1 to cEntries_
if lpnr1[I].lpRemoteName and lpnr1[I].dwDisplayType=RESOURCEDISPLAYTYPE_SERVER
peek(lpnr1[I].lpRemoteName,strname)
stop(strname)
end
if RESOURCEUSAGE_CONTAINER = band(lpnr1[I].dwUsage,RESOURCEUSAGE_CONTAINER)
lpnr2 = lpnr1[I]
loc:error_=GetNetRes_(lpnr2)
if clip(loc:error_)
nResult = WNetCloseEnum(hEnum)
return(clip(loc:error_))
end
end
end
elsif nResult = ERROR_NO_MORE_ITEMS
!stop('Error WNetEnumResource ERROR_NO_MORE_ITEMS '&nResult)
else
loc:error_ = 'Error WNetEnumResource '&nResult
end
nResult = WNetCloseEnum(hEnum)
else
loc:error_ = 'Error WNetOpenEnum '&nResult
end
return(clip(loc:error_))
- StillZero
- Ветеран
- Сообщения: 458
- Зарегистрирован: 06 Июль 2005, 2:17
- Откуда: Хабаровск
- Поблагодарили: 1 раз
- Контактная информация:
у меня этот код не работает: GPF-ит, не разбирался почемуцелесообразен ли такой вариант и будет ли поддерживаться на разных вариантах настройки сети
сетка большая: Microsoft + Netware, компов более 200, группы тоже есть конечно

в свое время я уже делал подобный "обзор" компьютеров, на моей сетке ОЧЕНЬ ТОРМОЗИТ, поэтому не рекомендую
IMO, как надо:
1. Должна быть таблица - список пользователей
2. Действие: "добавить пользователя" - выбирается имя компа обычным диалогом выбора компьютера
3. Действие: "поиск пользователей" - здесь можно разослать broadcast (разово) по всем машинам и получить отклики либо сделать "обзор" вышеописанным способом
4. Далее список юзеров проверяется по таймеру на активность/неактивность
- Олег
- Ветеран движения
- Сообщения: 122
- Зарегистрирован: 16 Июль 2005, 2:35
- Откуда: Москва
- Контактная информация:
Это не есть хороший вариант!
Если прога упадет, то данный экземпляр так и останется активным в вашей таблице!
Самый простой, и надежный (проверено на больших сетках в течении нескольких лет) вариант я уже как-то описывал.
Основной принцип - в каталоге БД выделяется некий каталог, в котором КАЖДЫЙ экземпляр проги, которая работает с этой БД, имеет свой "почтовый ящик" - небольшой файл с номером данного экземпляра программы. У меня это сделано автоматом - при запуске прога смотрит в INI-файл - есть там ее номер или нет. Если нет, то заходит в каталог почтовых ящиков и создает список имеющихся там файлов. Файлы имеют имя типа WKS.001 (до тысячи экземпляров)
Ищет максимальный номер и присваивает себе новый номер.
Далее - при запуске экземпляра проги ее почтовый ящик открывается в SHARE-режиме. При этом туда записывается инфа о сетевом имени компа, пользователе (компа и проги) и прочие локальные параметры. Если необходимо создать список экземпляров проги, которые работают в данный момент с БД, то сканируем все файлы - почтовые ящики и пытаемся каждый открыть в монопольном режиме. Если не удалось, то прога, связанная с данным почтовым ящиком, в данный момент работает. Открываем этот файл в SHARE-режиме и читаем из него всю необходимую инфу как о станции, так и о пользователе и локальных настройках. Можно дае оставить в этом файле сообщение для данной проги - если в проге включено сканирование почтового ящика по таймеру, то это сообщение будет считано и показано юзеру.
Основное преимущество данного метода - если прога "вылетела", то операционка сама тут-же закроет файл - почтовый ящик! И сканирование покажет, что данный файл закрыт, а значит прога, связанная с данным почтовым ящиком, неактивна!
Если прога упадет, то данный экземпляр так и останется активным в вашей таблице!
Самый простой, и надежный (проверено на больших сетках в течении нескольких лет) вариант я уже как-то описывал.
Основной принцип - в каталоге БД выделяется некий каталог, в котором КАЖДЫЙ экземпляр проги, которая работает с этой БД, имеет свой "почтовый ящик" - небольшой файл с номером данного экземпляра программы. У меня это сделано автоматом - при запуске прога смотрит в INI-файл - есть там ее номер или нет. Если нет, то заходит в каталог почтовых ящиков и создает список имеющихся там файлов. Файлы имеют имя типа WKS.001 (до тысячи экземпляров)
Ищет максимальный номер и присваивает себе новый номер.
Далее - при запуске экземпляра проги ее почтовый ящик открывается в SHARE-режиме. При этом туда записывается инфа о сетевом имени компа, пользователе (компа и проги) и прочие локальные параметры. Если необходимо создать список экземпляров проги, которые работают в данный момент с БД, то сканируем все файлы - почтовые ящики и пытаемся каждый открыть в монопольном режиме. Если не удалось, то прога, связанная с данным почтовым ящиком, в данный момент работает. Открываем этот файл в SHARE-режиме и читаем из него всю необходимую инфу как о станции, так и о пользователе и локальных настройках. Можно дае оставить в этом файле сообщение для данной проги - если в проге включено сканирование почтового ящика по таймеру, то это сообщение будет считано и показано юзеру.
Основное преимущество данного метода - если прога "вылетела", то операционка сама тут-же закроет файл - почтовый ящик! И сканирование покажет, что данный файл закрыт, а значит прога, связанная с данным почтовым ящиком, неактивна!