Передача данных по схеме "клиент-сервер"
Модератор: Модераторы
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Передача данных по схеме "клиент-сервер"
Понадобилось сделать простенький клиент-сервер. Нужно принимать запросы от нескольких клиентов (текст и потоки) одновременно и отправлять результат. Полдня сижу на формах и в гугле, пытаюсь найти дельный пример. Попробовал примеры Synapse, просто Sockets, ещё пару вариантов. Но как-то пока не могу добиться нужного результата. Примеры из дистрибутива Synapse под Lazarus не все компилятся, а пример их FCP (dsocksvr/dsockcli) не работает под Windows (мне нужен кросс-платформенный вариант).
Если кто-то сталкивался, поделитесь, плиз, примерчиком или ссылкой на него.
Если кто-то сталкивался, поделитесь, плиз, примерчиком или ссылкой на него.
Re: Передача данных по схеме "клиент-сервер"
Есть еще такой вариант (не кидайте камнями
) :
Шарится каталог на сервере. В нем сервер ищет запросы и формирует ответы. При регистрации - клиент формирует уникальный туннель. Туннель используется для именования файлов запросов и ответов.
Пример:
Клиент сформировал туннель - 6gh43e8y. Формирует запрос - 6gh43e8y.do, наполняет его директивой-текстом, и переименовывает в - 6gh43e8y.in. Переходит в режим ожидания ответа - 6gh43e8y.out.
Сервер, увидев запрос по маске *.in, подхватывает его к себе в память и стерает файл. Формирует ответ и записывает его в файл - 6gh43e8y.od, затем переименовывает в 6gh43e8y.out.
Клиент, нашедши ответ, подхватывает его к себе в память и стерает файл.
Скорость обмена данными при этом высокая. Масштабируемость присутствует. Ограничений, практически, нет. Использую уже несколько лет. Идея содрана у "Хакерс дизайн" и доработана.
Организовывал схемы:
сервер - каталог - клиенты
или
сервер - каталоги - клиенты
или
сервера - каталог - клиенты
или
сервер - каталоги - сервер-мосты - каталоги - клиенты
Грубо говоря - можно реализовывать любые схемы
Шарится каталог на сервере. В нем сервер ищет запросы и формирует ответы. При регистрации - клиент формирует уникальный туннель. Туннель используется для именования файлов запросов и ответов.
Пример:
Клиент сформировал туннель - 6gh43e8y. Формирует запрос - 6gh43e8y.do, наполняет его директивой-текстом, и переименовывает в - 6gh43e8y.in. Переходит в режим ожидания ответа - 6gh43e8y.out.
Сервер, увидев запрос по маске *.in, подхватывает его к себе в память и стерает файл. Формирует ответ и записывает его в файл - 6gh43e8y.od, затем переименовывает в 6gh43e8y.out.
Клиент, нашедши ответ, подхватывает его к себе в память и стерает файл.
Скорость обмена данными при этом высокая. Масштабируемость присутствует. Ограничений, практически, нет. Использую уже несколько лет. Идея содрана у "Хакерс дизайн" и доработана.
Организовывал схемы:
сервер - каталог - клиенты
или
сервер - каталоги - клиенты
или
сервера - каталог - клиенты
или
сервер - каталоги - сервер-мосты - каталоги - клиенты
Грубо говоря - можно реализовывать любые схемы
Последний раз редактировалось VirtUX 13.02.2011 00:47:43, всего редактировалось 1 раз.
Re: Передача данных по схеме "клиент-сервер"
Компонент Lnet, есть в Lazarus-CCR
посмотрите http://wiki.lazarus.freepascal.org/lNet
сам им пользовался, очень удачно, там на Socket, TCP пробовал
хотел написать свой протокол мессажинга и клиент + сервер для него.
так и не дописал, ессно... но компонент работал на ура
посмотрите http://wiki.lazarus.freepascal.org/lNet
сам им пользовался, очень удачно, там на Socket, TCP пробовал
хотел написать свой протокол мессажинга и клиент + сервер для него.
так и не дописал, ессно... но компонент работал на ура
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Re: Передача данных по схеме "клиент-сервер"
2VirtUX
Спасибо, но как-то слишком запутано получается. Да и файлы не хочется плодить (мне нужна обработка на стороне сервера, проще в памяти всё делать).
2hinst
Про lNet наслышан. Сейчас скачаю и попробую разобраться с примерами. Спасибо.
Спасибо, но как-то слишком запутано получается. Да и файлы не хочется плодить (мне нужна обработка на стороне сервера, проще в памяти всё делать).
2hinst
Про lNet наслышан. Сейчас скачаю и попробую разобраться с примерами. Спасибо.
Re: Передача данных по схеме "клиент-сервер"
2Nik
Совет - используйте http. Он максимально описан, не режется на разных прокси/шлюзах + не придется писать свои грабли.
Компоненты для клиента и сервера есть свободно, те же Synapse, Indy.
В вашем случае, инди может быть удобнее, поскольку простые примеры там значительно проще. И сервер в памяти может все запросы обрабатывать. Причем, одновременно.
Совет - используйте http. Он максимально описан, не режется на разных прокси/шлюзах + не придется писать свои грабли.
Компоненты для клиента и сервера есть свободно, те же Synapse, Indy.
В вашем случае, инди может быть удобнее, поскольку простые примеры там значительно проще. И сервер в памяти может все запросы обрабатывать. Причем, одновременно.
Re: Передача данных по схеме "клиент-сервер"
Indy тоже надо где-то искать?В вашем случае, инди может быть удобнее, поскольку простые примеры там значительно проще. И сервер в памяти может все запросы обрабатывать. Причем, одновременно.
А есть у кого нибудь пример использования сокетов?
Re: Передача данных по схеме "клиент-сервер"
Хм, гхм.
Компоненты Indy в стандартной поставке Lazarus.
За примерами и последней версией сюда: [url="www.indyproject.org/"]www.indyproject.org[/url]
Компоненты Indy в стандартной поставке Lazarus.
За примерами и последней версией сюда: [url="www.indyproject.org/"]www.indyproject.org[/url]
-
Padre_Mortius
- энтузиаст
- Сообщения: 1265
- Зарегистрирован: 29.05.2007 17:38:07
- Откуда: Спб
Re: Передача данных по схеме "клиент-сервер"
Timid
А откуда взялись компоненты Indy в стандартной поставке Lazarus? Их там отродясь не было. В поставке fpc присутствуют компоненты curl, lnet, а в лазарусе только lazwebextra.
А откуда взялись компоненты Indy в стандартной поставке Lazarus? Их там отродясь не было. В поставке fpc присутствуют компоненты curl, lnet, а в лазарусе только lazwebextra.
Re: Передача данных по схеме "клиент-сервер"
А где найти рабочий 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, установил, счастлив )
Отвечу сам на свой вопрос.
1. Скачал indy-10.2.0.3.zip;
2. Содержимое папок fpc и lazarus из скачанного архива переместил в lazarus\fpc\2.4.2\units\i386-win32\indy;
3. Запустил indylaz.lpk, установил, счастлив )
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Re: Передача данных по схеме "клиент-сервер"
Собственно, по мере появления свободного времени колупаю тему. Сейчас пытаюсь заставить работать клиент-сервер на базе сокетов силами Synapse. Вроде всё собрал по примерами, логика в порядке. Но не работает, хоть ты тресни.
Кто-нибудь ткните меня носом в косяк, плиз. Код - во вложении.
Добавлено спустя 1 час 19 минут 58 секунд:
Всё, нашёл таки глупую багу. Я тестил в Win7/Vista по сетке. "Семёрка" по дефолту юзает IPv6. Соответственно, если прописать в параметрах сокета "127.0.0.1" - это будет нифига не обычный Localhost для Ipv6.
Пока принудительно переключил TTCPBlockSocket в режим Ipv4. Для работы в локалке большего не надо по-любому.
Добавлено спустя 3 минуты 42 секунды:
PS. Небольшой оффтопик - как запускать функцию AttendConnection из моего кода в отдельном потоке при каждом вызове? Киньте ссылкой в примерчик, пока чего-то не могу нагуглить...
Кто-нибудь ткните меня носом в косяк, плиз. Код - во вложении.
Добавлено спустя 1 час 19 минут 58 секунд:
Всё, нашёл таки глупую багу. Я тестил в Win7/Vista по сетке. "Семёрка" по дефолту юзает IPv6. Соответственно, если прописать в параметрах сокета "127.0.0.1" - это будет нифига не обычный Localhost для Ipv6.
Пока принудительно переключил TTCPBlockSocket в режим Ipv4. Для работы в локалке большего не надо по-любому.
Добавлено спустя 3 минуты 42 секунды:
PS. Небольшой оффтопик - как запускать функцию AttendConnection из моего кода в отдельном потоке при каждом вызове? Киньте ссылкой в примерчик, пока чего-то не могу нагуглить...
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Re: Передача данных по схеме "клиент-сервер"
Очень просто:
И всё.
ps Могут быть ошибки в синтаксисе т.к. код набирал в браузере
Код: Выделить всё
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 Могут быть ошибки в синтаксисе т.к. код набирал в браузере
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Re: Передача данных по схеме "клиент-сервер"
2Mr.Smart
Спасибо
Завтра на свежую голову проверю 
Добавлено спустя 12 часов 29 минут 14 секунд:
2Mr.Smart
Сделал потоки по вашему примеру. При запуске под отладчиком при старте потока всё валится. Без отладчика - просто виснет. Поотлаживал малость - судя по всему виснет уже после создания потока, при попытке работать с сокетом, который в потоке создан.
Добавлено спустя 2 часа 16 минут:
Собственно, нашёл ответ на форуме. Не знал, что в потоке нельзя работать с окном/вызывать ShowMessage. В принципе, мне оно только для отладки надо - в реале программа всё равно будет работать с файлами, а отладку можно и в лог писать.
Спасибо
Добавлено спустя 12 часов 29 минут 14 секунд:
2Mr.Smart
Сделал потоки по вашему примеру. При запуске под отладчиком при старте потока всё валится. Без отладчика - просто виснет. Поотлаживал малость - судя по всему виснет уже после создания потока, при попытке работать с сокетом, который в потоке создан.
Добавлено спустя 2 часа 16 минут:
Собственно, нашёл ответ на форуме. Не знал, что в потоке нельзя работать с окном/вызывать ShowMessage. В принципе, мне оно только для отладки надо - в реале программа всё равно будет работать с файлами, а отладку можно и в лог писать.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
- Nik
- энтузиаст
- Сообщения: 573
- Зарегистрирован: 03.02.2006 23:08:09
- Откуда: Киров
- Контактная информация:
Re: Передача данных по схеме "клиент-сервер"
Одностороннюю передачу отшлифовал до блеска. Тестировал в сети - бомбил с нескольких компов несколькими миллионами пакетов, ни одного байта не пропало
Но есть ещё один момент, с которым не могу пока разобраться. Есть связка клиент-сервер на базе блокирующих сокетов (всё тот же класс TTCPBlockSocket из Synapse). Создаём канал сокет-сокет, передаём данные от клиента к серверу. С этим проблем нет. А вот как отправить по установленному каналу ответ? Пробовал на сервере сразу после приёма данных с помощью RecvString выполнял отправку с того же сокета (на клиенте, соответственно, наоборот - после отправки включал "прослушку"). Но данные не приходят. Хотя и ошибок сокет не возвращает.
Пните, плиз, в подходящем направлении - куда копать?
Добавлено спустя 2 часа 52 секунды:
Всё, разобрался. Косяк был в настройках роутера - пакеты на нужный порт терялись в обратном направлении

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