Передача данных по схеме "клиент-сервер"

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Передача данных по схеме "клиент-сервер"

Сообщение Nik » 12.02.2011 22:22:19

Понадобилось сделать простенький клиент-сервер. Нужно принимать запросы от нескольких клиентов (текст и потоки) одновременно и отправлять результат. Полдня сижу на формах и в гугле, пытаюсь найти дельный пример. Попробовал примеры Synapse, просто Sockets, ещё пару вариантов. Но как-то пока не могу добиться нужного результата. Примеры из дистрибутива Synapse под Lazarus не все компилятся, а пример их FCP (dsocksvr/dsockcli) не работает под Windows (мне нужен кросс-платформенный вариант).

Если кто-то сталкивался, поделитесь, плиз, примерчиком или ссылкой на него.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Передача данных по схеме "клиент-сервер"

Сообщение VirtUX » 13.02.2011 01:41:34

Есть еще такой вариант (не кидайте камнями :) ) :
Шарится каталог на сервере. В нем сервер ищет запросы и формирует ответы. При регистрации - клиент формирует уникальный туннель. Туннель используется для именования файлов запросов и ответов.
Пример:
Клиент сформировал туннель - 6gh43e8y. Формирует запрос - 6gh43e8y.do, наполняет его директивой-текстом, и переименовывает в - 6gh43e8y.in. Переходит в режим ожидания ответа - 6gh43e8y.out.
Сервер, увидев запрос по маске *.in, подхватывает его к себе в память и стерает файл. Формирует ответ и записывает его в файл - 6gh43e8y.od, затем переименовывает в 6gh43e8y.out.
Клиент, нашедши ответ, подхватывает его к себе в память и стерает файл.
Скорость обмена данными при этом высокая. Масштабируемость присутствует. Ограничений, практически, нет. Использую уже несколько лет. Идея содрана у "Хакерс дизайн" и доработана.
Организовывал схемы:
сервер - каталог - клиенты
или
сервер - каталоги - клиенты
или
сервера - каталог - клиенты
или
сервер - каталоги - сервер-мосты - каталоги - клиенты
Грубо говоря - можно реализовывать любые схемы :)
Последний раз редактировалось VirtUX 13.02.2011 01:47:43, всего редактировалось 1 раз.
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Передача данных по схеме "клиент-сервер"

Сообщение hinst » 13.02.2011 01:46:25

Компонент Lnet, есть в Lazarus-CCR
посмотрите http://wiki.lazarus.freepascal.org/lNet
сам им пользовался, очень удачно, там на Socket, TCP пробовал
хотел написать свой протокол мессажинга и клиент + сервер для него.
так и не дописал, ессно... но компонент работал на ура
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Передача данных по схеме "клиент-сервер"

Сообщение Nik » 13.02.2011 17:49:05

2VirtUX
Спасибо, но как-то слишком запутано получается. Да и файлы не хочется плодить (мне нужна обработка на стороне сервера, проще в памяти всё делать).


2hinst
Про lNet наслышан. Сейчас скачаю и попробую разобраться с примерами. Спасибо.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Передача данных по схеме "клиент-сервер"

Сообщение Timid » 14.02.2011 09:05:53

2Nik

Совет - используйте http. Он максимально описан, не режется на разных прокси/шлюзах + не придется писать свои грабли.
Компоненты для клиента и сервера есть свободно, те же Synapse, Indy.

В вашем случае, инди может быть удобнее, поскольку простые примеры там значительно проще. И сервер в памяти может все запросы обрабатывать. Причем, одновременно.
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Передача данных по схеме "клиент-сервер"

Сообщение Sheleh » 16.02.2011 15:35:36

В вашем случае, инди может быть удобнее, поскольку простые примеры там значительно проще. И сервер в памяти может все запросы обрабатывать. Причем, одновременно.
Indy тоже надо где-то искать?

А есть у кого нибудь пример использования сокетов?
Sheleh
новенький
 
Сообщения: 24
Зарегистрирован: 12.11.2010 18:31:07

Re: Передача данных по схеме "клиент-сервер"

Сообщение Timid » 16.02.2011 15:43:51

Хм, гхм.
Компоненты Indy в стандартной поставке Lazarus.

За примерами и последней версией сюда: [url="www.indyproject.org/"]www.indyproject.org[/url]
Timid
постоялец
 
Сообщения: 290
Зарегистрирован: 21.11.2007 21:33:15

Re: Передача данных по схеме "клиент-сервер"

Сообщение Padre_Mortius » 16.02.2011 22:03:32

Timid
А откуда взялись компоненты Indy в стандартной поставке Lazarus? Их там отродясь не было. В поставке fpc присутствуют компоненты curl, lnet, а в лазарусе только lazwebextra.
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: Передача данных по схеме "клиент-сервер"

Сообщение Sheleh » 17.02.2011 08:01:44

А где найти рабочий Indy под lazarus 0.9.31? Ни indy-10.2.0.3.zip, ни Indy9 не компилируются у меня.

Отвечу сам на свой вопрос.
1. Скачал indy-10.2.0.3.zip;
2. Содержимое папок fpc и lazarus из скачанного архива переместил в lazarus\fpc\2.4.2\units\i386-win32\indy;
3. Запустил indylaz.lpk, установил, счастлив )
Sheleh
новенький
 
Сообщения: 24
Зарегистрирован: 12.11.2010 18:31:07

Re: Передача данных по схеме "клиент-сервер"

Сообщение Nik » 30.04.2011 19:57:59

Собственно, по мере появления свободного времени колупаю тему. Сейчас пытаюсь заставить работать клиент-сервер на базе сокетов силами Synapse. Вроде всё собрал по примерами, логика в порядке. Но не работает, хоть ты тресни.

Кто-нибудь ткните меня носом в косяк, плиз. Код - во вложении.

Добавлено спустя 1 час 19 минут 58 секунд:
Всё, нашёл таки глупую багу. Я тестил в Win7/Vista по сетке. "Семёрка" по дефолту юзает IPv6. Соответственно, если прописать в параметрах сокета "127.0.0.1" - это будет нифига не обычный Localhost для Ipv6.
Пока принудительно переключил TTCPBlockSocket в режим Ipv4. Для работы в локалке большего не надо по-любому.

Добавлено спустя 3 минуты 42 секунды:
PS. Небольшой оффтопик - как запускать функцию AttendConnection из моего кода в отдельном потоке при каждом вызове? Киньте ссылкой в примерчик, пока чего-то не могу нагуглить...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Передача данных по схеме "клиент-сервер"

Сообщение Mr.Smart » 30.04.2011 21:31:01

Очень просто:
Код: Выделить всё
type
  TSockThread=class(TThread)
  private
    fSock: TTCPBlockSocket;
  protected
    procedure Execude; override;
  public
    constructor Create(aSock: TSocket);
    destructor Destroy; override;
  end;
....
constructor TSockThread.Create(aSock: TSocket);
begin
  FreeOnTerminate:=True;

  fSock:=TTCPBlockSocket.Create;

  fSock.Socket:=aSock;

  inherited Create(False);
end;

destructor TSockThread.Destroy;
begin
  fSock.Free;
  inherited;
end;

procedure TSockThread.Execute;
begin
  fSock. // bla bla bla
end;

...
begin
...
   if fSock.CanRead(1000) then
    begin
     ClientSock:=fSock.Accept;
     if fSock.LastError=0 then
      TSockThread.Create(ClientSock);
    end;
...
end;

И всё.
ps Могут быть ошибки в синтаксисе т.к. код набирал в браузере :wink:
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Передача данных по схеме "клиент-сервер"

Сообщение Nik » 30.04.2011 23:07:31

2Mr.Smart
Спасибо :) Завтра на свежую голову проверю :)

Добавлено спустя 12 часов 29 минут 14 секунд:
2Mr.Smart
Сделал потоки по вашему примеру. При запуске под отладчиком при старте потока всё валится. Без отладчика - просто виснет. Поотлаживал малость - судя по всему виснет уже после создания потока, при попытке работать с сокетом, который в потоке создан.

Добавлено спустя 2 часа 16 минут:
Собственно, нашёл ответ на форуме. Не знал, что в потоке нельзя работать с окном/вызывать ShowMessage. В принципе, мне оно только для отладки надо - в реале программа всё равно будет работать с файлами, а отладку можно и в лог писать.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров

Re: Передача данных по схеме "клиент-сервер"

Сообщение Nik » 04.05.2011 16:45:35

Одностороннюю передачу отшлифовал до блеска. Тестировал в сети - бомбил с нескольких компов несколькими миллионами пакетов, ни одного байта не пропало :)

Но есть ещё один момент, с которым не могу пока разобраться. Есть связка клиент-сервер на базе блокирующих сокетов (всё тот же класс TTCPBlockSocket из Synapse). Создаём канал сокет-сокет, передаём данные от клиента к серверу. С этим проблем нет. А вот как отправить по установленному каналу ответ? Пробовал на сервере сразу после приёма данных с помощью RecvString выполнял отправку с того же сокета (на клиенте, соответственно, наоборот - после отправки включал "прослушку"). Но данные не приходят. Хотя и ошибок сокет не возвращает.
Пните, плиз, в подходящем направлении - куда копать?

Добавлено спустя 2 часа 52 секунды:
Всё, разобрался. Косяк был в настройках роутера - пакеты на нужный порт терялись в обратном направлении :) :(
Аватара пользователя
Nik
энтузиаст
 
Сообщения: 573
Зарегистрирован: 04.02.2006 00:08:09
Откуда: Киров


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 47

Рейтинг@Mail.ru