Сейчас на форуме: hgdagon, asfa (+4 невидимых)

 eXeL@B —› Программирование —› Сокеты, трэды и Делфи. Клиент-сервер.
Посл.ответ Сообщение

Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 23 февраля 2007 07:05
· Личное сообщение · #1

Смысл такой: есть ведущие (тип I) и ведомые (тип II) клиентские проги. Ведомые ставятся на компы, запускаются автоматом и содержат несколько видов функций (аля макросов). Ведущие проги ставятся на другие компы и позволяют рулить ведомыми (здесь юзер кликнул баттон - на ведомом компе выполнилось действие). На всё это хозяйство должен быть один сервер, так чтобы и ведущие и ведомые к нему коннектились, а ведомые получали указания от сервера от ведущих. Немного мудрёно, поэтому поясню: суть сервера - интерпретировать команды и выступать посредником между парой "ведущий-ведомый". Т.е. всёго 2 типа клиентов. Ну во всяком случае для того что я описал я вижу именно такую схему.

Видится в этой задача мне всё, кроме вот чего: ведомые работают на неблокирующем сокете, а ведущие - на блокирующем (каждому такому клиенту - по трэду). Вопрос вот в чем: как безопасно переслать команду из потока ведущего в поток ведомого?

-----
Я медленно снимаю с неё UPX... *FF_User*




Ранг: 29.0 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 23 февраля 2007 11:27
· Личное сообщение · #2

если пральна понял: поток ведущий и поток ведомый запущены в одной проге тогда управлять через управляющую структуру. те в главном потоке когда создаеться новый поток созадеться структура к которому имеет доступ созданый поток, и через эту структуру предаюся




Ранг: 240.5 (наставник)
Активность: 0.190
Статус: Участник
Author of ACKiller

Создано: 23 февраля 2007 11:33
· Личное сообщение · #3

Создавай список потоков, каждый элемент которого является указателем на список задач (ну или запросов) конкретного потока. Причем этот список задач лучше сделать двухсвязным списком, если сами запросы небольшие.




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 23 февраля 2007 11:44 · Поправил: s0larian
· Личное сообщение · #4

AlexZ, я делал такие вещи вот как:
- сервер: имеет UI (главный поток) и ещё один поток для обработки всех клиентских соединений. Поток имеет listening socket а также список connected sockets. Почти все операции non-blocking: recv(), listen() - реализутся через select(). send() можно делать в blocking - так проще. Дополнительные потоки не нужны.
- клиенты: имеют UI (или не создают ничего видимого) и ещё один поток который делает connect() и потом recv() в blocking режиме. Тут всё просто - recv() возвращаеццо, парсишь сообщение и передаёшь данные в главный поток через PostMessage(). В главном потоке, например, добавляешь строчку в list box, и выполняешь действие.

voila!

З.Ы. это все а win32 API, но в Delphi будут компоненты для всего этого. Если нужна помощь на С++/API - спрашивай.



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 24 февраля 2007 03:34
· Личное сообщение · #5

Друзья, спасибо за участие в мозговом штурме!
Будут вопросы - спрошу ;)

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 26 февраля 2007 10:28
· Личное сообщение · #6

AlexZ, ну как там прогресс? Кста, если ты знаешь С, то можно сделать пару мелких примеров что бы понять комуникационную модель. Ну а потом переведёшь это всё в свой Дельфи с компонентами, UI, и прочей мишурой



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 26 февраля 2007 22:44
· Личное сообщение · #7

s0larian, прогресса пока нет, из отпуска выйду на след. неделе и снова воевать с клиентами
С знаю плохо "сам не разговаривать, только понимать". К счастью, ведомые клиенты уже есть и к сожалению они ужасны, поэтому задача состоит в том, чтобы посредством нормального интерфейса ведущих клиентов управлять ведомыми через сервер. "Вот такой вот геморой нам придумала партия"

-----
Я медленно снимаю с неё UPX... *FF_User*




Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 28 февраля 2007 09:58
· Личное сообщение · #8

Я вот тоже воюю с сотевыми приблудами )))
Мой прога применяет TServerSocket и раз в n сек. рассылает всем законнекченным клиентам один и тот же буфер. А клиенты а-ля TClientSocket это все принимают и что-то делают свое черное с принятым от сервера буфера. Так вот глюк в том что от сервера идет пакет скажем на 2308 байт, а вот не все клиенты принимают полностью этот пакет! бывает что в момент времени Т1 клиент К1 принимет 1460 байт, а через хз ско-ко времени и периодов приема может принять полностью 2308 байт!
Вот хз как быть дальше, пока ищу ответ в сорцах, мож найду

-----
My love is very cool girl.





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 28 февраля 2007 17:04 · Поправил: s0larian
· Личное сообщение · #9

theCollision, какой протокол ты используешь? TCP? Если так, то данные могут быть разбиты на сколько угодно сетевых пакетов (то что видит sniffer). TCP это поток данных и recv() может вернуться сколько угодно раз - зависит от того сколько приходит сетевых пакетов и конфигурации сокета. (то есть ты можешь сказать что б recv() возврачал минимум N байтов)

Обычно люди пишут мелкий заголовок такого типа:


struct MessageHeader
{
uint32 type, totalLength;
};


потом идут данные. Ну и клиент вызывает recv() пока не получит sizeof(MessageHeader) а потом ещё пока не получит всё сообщение.



Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 28 февраля 2007 22:18
· Личное сообщение · #10

Вот кусок рассылки сервером:
procedure TNkTecServer.Send;
var
I : Integer;
begin
for I := 0 to FServer.Socket.ActiveConnections - 1 do
begin
CopyMemory(FServer.Socket.Connections[I].Data,Buffer,FSizeOfBuf);
FServer.Socket.Connections[I].SendBuf(FServer.Socket.Connections[I].Da ta^,
FSizeOfBuf);
Sleep(200);
end;
end;

Вот в что написано у меня в обработчике TClientSocket.OnRead :

SizeOfBuf := Socket.ReceiveLength;
Socket.ReceiveBuf(Buffer,SizeOfBuf);

Дальше махинации с принятым буфером.

Вроде бы все ок!

Но при работе серверной части:
01.03.2007 08:38:11 [options.xml] Opened
01.03.2007 08:38:13 [Network] Connect: 10.128.3.56
01.03.2007 08:38:38 [Network] Connect: 10.128.3.56
01.03.2007 08:38:53 [Network] Disconnect: 10.128.3.56
01.03.2007 08:38:58 [Network] Connect: 10.128.3.56
01.03.2007 08:39:13 [Network] Disconnect: 10.128.3.56

....................................................

01.03.2007 08:57:58 [Network] Connect: 10.128.3.56
01.03.2007 08:58:00 [Network] Disconnect: 10.128.3.56
01.03.2007 08:58:13 [Network] Disconnect: 10.128.3.56

Вот ну никак не пойму, почему клиент, два раза коннектиться и дисконнектиться и постоянно коннектдисконнект (

-----
My love is very cool girl.




Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 02 марта 2007 04:28
· Личное сообщение · #11

theCollision, вот та же шняга и у меня... Чисто для статистики стал добавлять в лог коннекты/дисконнекты и пошло нахъ =( Ещё один ньюанс: в свойствах Т-сокета АйПи - это не АйПи клиента, а АйПи самой верхней машины, т.е. при клиентских коннектах от одного провайдера получаем ИП прова один и тот же.

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 02 марта 2007 10:00
· Личное сообщение · #12

theCollision, с Дельфой помочь не могу, но, если хочешь, можем переписать на API. Ты можешь вызывать connect(), bind(), accept() и select() из паскаля?



Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 02 марта 2007 11:05
· Личное сообщение · #13

s0larian
Я не просто могу, я вынужден, потому что я начал писать свой компонент ))) Жалко что абстрактного класса нету, под сокеты, который бы описывал че может TSeverSocket (((

-----
My love is very cool girl.





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 02 марта 2007 14:03
· Личное сообщение · #14

theCollision, ок, так с чем тебе помочь? что уже есть?



Ранг: 54.0 (постоянный)
Активность: 0.020
Статус: Участник

Создано: 02 марта 2007 15:11
· Личное сообщение · #15

theCollision пишет:
Я не просто могу, я вынужден, потому что я начал писать свой компонент ))) Жалко что абстрактного класса нету, под сокеты, который бы описывал че может TSeverSocket (((

TAbstractSocket, TCustomSocket, TCustomServerSocket, TServerSocket? хелп к дельфе рулит. для последнего есть даже "Using server sockets", с примерами.
На torry.net фришных socket серверов куча. Сильно хочется пример - выкачать несколько и посмотреть что и как. Есть синапс (реально рулит), но там не объекты, там тоже типа апи и только блокирующие сокеты.



Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 02 марта 2007 22:02
· Личное сообщение · #16

n1kto
Ты глянь на эти сорцы ))), Там же уже много вещей переопределено и сделано!!! А абстрактный класс - это когда не содержатся, только и только виртуальные методы. Замечу, если ты сейчас создашь объекты от классов что ты предложил, компиллер сделает объекты!!! А из букваря известно, что от абстрактных классов - не может быть создан объект!!!

s0larian
Я не могу определиться, какую модель мне брать? На портах-завершения? Тогда где почитать, чтобы по толковей описано было?

-----
My love is very cool girl.




Ранг: 54.0 (постоянный)
Активность: 0.020
Статус: Участник

Создано: 02 марта 2007 22:42
· Личное сообщение · #17

theCollision пишет:
А абстрактный класс - это когда не содержатся, только и только виртуальные методы.

В этом смысле абстрактными в дельфи являются интерфейсы. определи и трахайся до посинения

theCollision пишет:
А из букваря известно, что от абстрактных классов - не может быть создан объект!!!

определяем интерфейс и пытаемся сделать из него объект. не получается. значит, компилятор не работает
В дельфи от любого класса может быть создан объект, так как все классы происходят от общего предка имеющего неабстрактное содержимое. курим букварь по дельфи

я не очень понял, чем тебя классическая модель автомата не устраивает? биндишь сокет, на accept вешаешь создание нового треда, который рулит конкретным соединением... вроде все просто? кстати, два коннекта и дисконнекта могут расти именно отсюда - порт-листен и реально рабочий - разные.



Ранг: 271.5 (наставник), 12thx
Активность: 0.150
Статус: Участник
Packer Reseacher

Создано: 02 марта 2007 23:37
· Личное сообщение · #18

n1kto
И переписывай добрую кучу уже написанных программ на предприятии ))). Нафиг надо! Уж лучше компонент с такими же свойствами, методами.

-----
My love is very cool girl.





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 05 марта 2007 13:55
· Личное сообщение · #19

theCollision, не трогай Completion Ports для начала, запаришься


 eXeL@B —› Программирование —› Сокеты, трэды и Делфи. Клиент-сервер.
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати