Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.08.2015, 12:11   #11
Dux
Delphi Master
Форумчанин Подтвердите свой е-майл
 
Аватар для Dux
 
Регистрация: 31.03.2008
Сообщений: 803
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Ну тогда вопрос решен. Адрес сервера и пост-запрос. Парсим запрос к серваку и всй тип-топ.
Да на словах понятно мне бы примерчик на дельфи
Dux вне форума Ответить с цитированием
Старый 14.08.2015, 12:16   #12
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от Dux Посмотреть сообщение
Да на словах понятно мне бы примерчик на дельфи
Да, причём сдесь делфи, Фортран, Бейсик или Си? Алгоритмов, хоть Ж... жуй. Так и скажи, искать не хочу и не умею...
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 14.08.2015, 13:05   #13
ДралсяСошибками
Форумчанин
 
Аватар для ДралсяСошибками
 
Регистрация: 31.05.2011
Сообщений: 301
По умолчанию

Может не совсем то, как-то делал в чате, для составления списка присутствующих плебеев:
Код:
program Server;

{$APPTYPE CONSOLE}

uses
  Windows, SysUtils, Winsock;

const
  Resourse = 'Client: %0:s:%1:s - %2:s';

var
  WWSAData: TWSAData;
  WSocket, WListenSocket: TSocket;
  WSockAddr: TSockAddr;
  TreadID: THandle;
  FDSet: TFDSet;

procedure SocketThread;
var
  Buf: String;
  Size, SizeRecv, SizeBuf, i: Integer;
  ClientAddr: TSockAddr;
  ClientSocket: TSocket;
begin
  ClientSocket := WSocket;
    if ClientSocket = INVALID_SOCKET then Exit;
      Size := SizeOf(TSockAddr);
      GetPeerName(ClientSocket, ClientAddr, Size);
      FD_SET(ClientSocket, FDSet);
      WriteLn('Clients: ' + IntToStr(FDSet.fd_count));
      WriteLn(Format(Resourse, [inet_ntoa(ClientAddr.sin_addr), IntToStr(htons(ClientAddr.sin_port)), 'connect']));
      Size := SizeOf(Integer);
      GetSockOpt(WSocket, SOL_SOCKET, SO_RCVBuf, @SizeBuf, Size);
        repeat
          SetLength(Buf, High(Word));
          SizeRecv := Recv(ClientSocket, Buf[1], Length(Buf), 0);
            if SizeRecv <= 0 then Break;
              SetLength(Buf, SizeRecv);
              WriteLn(Format(Resourse, [inet_ntoa(ClientAddr.sin_addr), IntToStr(htons(ClientAddr.sin_port)), Buf]));
                for i := 0 to FDSet.fd_count - 1 do
                  if Send(FDSet.fd_array[i], Buf[1], Length(Buf), 0) = SOCKET_ERROR then Break;
        until False;
  WriteLn(Format(Resourse, [inet_ntoa(ClientAddr.sin_addr), IntToStr(htons(ClientAddr.sin_port)), 'disconnect']));
  FD_CLR(ClientSocket, FDSet);
  WriteLn('Clients: ' + IntToStr(FDSet.fd_count));
  CloseSocket(ClientSocket);
end;

begin
  if WSAStartup($202, WWSAData) <> 0 then Halt;
    WListenSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
      if WListenSocket = INVALID_SOCKET then Halt;
        FillChar(WSockAddr, SizeOf(TSockAddr), 0);
        WSockAddr.sin_family := AF_INET;
        WSockAddr.sin_port := htons(1111);
        WSockAddr.sin_addr.s_addr := inet_addr('127.0.0.1');
          if Bind(WListenSocket, WSockAddr, SizeOf(TSockAddr)) <> 0 then Halt;
            if Listen(WListenSocket, SOMAXCONN) <> 0 then Halt;
              WriteLn('Listening...');
              FD_ZERO(FDSet);
                repeat
                  WSocket := Accept(WListenSocket, nil, nil);
                  CreateThread(nil, 0, @SocketThread, nil, 0, TreadID);
                until False;
  CloseSocket(WListenSocket);
  WSACleanup;
end.
Код:
program Client;

{$APPTYPE CONSOLE} 

uses
  Windows, Winsock;

var
  WWSAData: TWSAData;
  WSocket: TSocket;
  WSockAddr: TSockAddr;
  TreadID: THandle;
  SendBuf: String;

procedure SocketThread;
var
  RecvBuf: String;
  Size: Integer;
begin
  repeat
    SetLength(RecvBuf, High(Word));
    Size := Recv(WSocket, RecvBuf[1], Length(RecvBuf), 0);
      if Size <= 0 then Halt;
    SetLength(RecvBuf, Size);
    WriteLn(RecvBuf);
  until False;
end;

begin
  if WSAStartup($202, WWSAData) <> 0 then Halt;
    WSocket := Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
      if WSocket = INVALID_SOCKET then Halt;
        FillChar(WSockAddr, SizeOf(TSockAddr), 0);
        WSockAddr.sin_family := AF_INET;
        WSockAddr.sin_port := htons(1111);
        WSockAddr.sin_addr.s_addr := inet_addr('127.0.0.1');
          if Connect(WSocket, WSockAddr, SizeOf(TSockAddr)) = SOCKET_ERROR then Halt;
            CreateThread(nil, 0, @SocketThread, nil, 0, TreadID);
              repeat
                ReadLn(SendBuf);
                  if Send(WSocket, SendBuf[1], Length(SendBuf), 0) = SOCKET_ERROR then Break;
              until False;
    CloseSocket(WSocket);
    WSACleanup;
end.
Вложения
Тип файла: zip 555.ZIP (35.4 Кб, 5 просмотров)
ДралсяСошибками вне форума Ответить с цитированием
Старый 14.08.2015, 17:30   #14
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от Smitt&Wesson Посмотреть сообщение
Ну тогда вопрос решен. Адрес сервера и пост-запрос.
Не все так просто. Это сработает, если учитывать одно условие, а именно, если программа всегда будет корректно закрываться и отправлять пост-запрос. В случае, если программу закроют через диспетчер задач или, как уже писали выше, отключат электричество, то у нас будет +1 вечный пользователь в базе сайта.

Возможно тут нужно смотреть в сторону WebSocket'ов.
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).

Последний раз редактировалось Krasiosoft; 14.08.2015 в 17:47.
Krasiosoft вне форума Ответить с цитированием
Старый 14.08.2015, 17:51   #15
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
А как ты будешь обрабатывать ситуацию выключения света?
Сообщение можно в цикле посылать. Раз в 10 минут скажем. Не пришло ни разу за пол часа - бобик сдох. Я примерно так отлавливаю на сервере приложений сдохших клиентов по причине то ли из розетки на ходу, тол ли комп завис и прочая не вкусность. Мои пользователи все могут
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 14.08.2015, 18:41   #16
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Так это можно в БД свой айпи отправлять. Там настроек минимум. А сервак пусть чистит старые записи, раз в сутки например.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 14.08.2015, 19:50   #17
Dux
Delphi Master
Форумчанин Подтвердите свой е-майл
 
Аватар для Dux
 
Регистрация: 31.03.2008
Сообщений: 803
По умолчанию

Спасибо большое за советы! Буду копать.
Dux вне форума Ответить с цитированием
Старый 14.08.2015, 21:27   #18
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Так это можно в БД свой айпи отправлять.
Не только IP, а ещё м МАС.
А ещё лучше - привязка к железу, ведь VID/DID железа не меняется так часто и не зависит от структуры сети клиента. Поэтому, неплохую уникальность будет иметь, например, МАС-адрес текущего коннекта "DC-A9-71-71-18-89", поксоренный на ID корневого USB-концентратора "USB\ROOT_HUB20&VID8086&PID1C2D&REV 0004"; для фиксации длины можно из этого посчитать MD5 и в таком виде слать на сервер и хранить там в базе (в файле?) в отсортированном виде (бинарн. поиск).

Вот такой бред сгенерировал мой воспалённый мозг. Так сервер будет знать, что с опред. компа зашли повторно, не выйдя штатно в прошлый раз.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 18.08.2015, 16:41   #19
spirit-ua
Форумчанин
 
Аватар для spirit-ua
 
Регистрация: 04.06.2009
Сообщений: 351
По умолчанию

реализовал как то похожую задачу таким методом:
1. Идентифицировал пользователя, каждая копия программы имела свой уникальный ключ. У вас видимо это будет ай-пи что не совсем подходит т.к. машина может выходить из локалки через прокси со всеми вытекающими или мак, что более правильно но тут вопрос: сможет ли прога вытащить мак (механизм, права пользователя и т.д.)? В любом случае вам нужно отловить уникального пользователя (копию программы) по уникальному параметру
2. Программа один раз в минуту (час, сутки) отсылает на сервер некий запрос и уже сервак (скрипт) ложит в файл (БД) запись с идентификатором пользователя (копией программы) и временем получения запроса
3. Сервак (скрипт, программа) листает все записи в файле (БД) и смотрит если не было ответа от программы в течении минуты (часа, суток) отмечает что программа (пользователь) активен\неактивен

Думаю суть изложил доходчиво
Мне разрешено открывать только одну страницу - about :blank. Сперва было скучно, но потом я втянулся. Теперь у меня там живет 2 виртуальных друга, и я слышу голоса из розетки!
spirit-ua вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как узнать количество выбранных checkbox Notan1310 C# (си шарп) 0 11.06.2015 20:09
Узнать количество подключенных пользователей Aleksandr Работа с сетью в Delphi 2 05.04.2013 16:04
Как узнать сколько пользователей подключилось к заданному Алиасу BDE grenles БД в Delphi 0 11.11.2009 23:02
Как узнать количество рисунков в документе? Busine2009 Microsoft Office Word 7 15.07.2009 18:26
Как узнать количество таблиц в базе udpflood БД в Delphi 2 27.03.2009 00:06