Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как лучше реализовывать архитектуру клиент-сервер [D7, WinXP]


Страницы:   1 2 3

bobah ©   (2006-07-12 16:43:00) 

Здравствуйте.

Начну с описания. Существует у меня три вида программ. 1 - БД , 2 - сервер опроса приборов (клиент БД), 3 - клиентское ПО (ПО с которым взаимодействует пользователь). Это не трехзвенная модель в полном понимании.  Программа 3 допустим вставляет запись в БД, при этом обращается непосредственно в БД. В программе 3 есть журнал событий, котором отображаются изменения БД. Для того чтобы сообщить всем клиентам об изменениях прога 3 взаимодействует с 2 с помощью сокетов. То есть по сокетам передаются сообщения типа refresh. Клиент посылает серверу опроса сообщение, а сервер опроса рассылает это же сообщение всем остальным клиентам.
Теперь конкретнее. Я использую WinSock 2.2 асинхронную модель на событиях. С клиентом всё ясно, а вот с сервером не всё. Важно чтобы сообщения, приходящие на сервер, уходили на другие клиенты в том порядке, в котором они приходят на сервер. Как это обеспечить?
На данный момент серверная часть работает в одном отдельном потоке. Причем события read от всех клиентов обрабатываются в одной функции WSAWaitForMultipleEvents.


Сергей М.   (2006-07-13 09:05:00) [41]


> уходили на другие клиенты


А где у тебя в коде это происходит ? Я не вижу ..
Чтение данных из некоего гнезда в коде фигурирует , а записи данных в некие гнезда нигде нет ..

Я вообще не вижу причин ставить под сомнение тот самый "порядок". TCP - поточно-ориентированный протокол, прием-передача данных в нем организована по принципу, сходному с FIFO (очередь). Если передатчик отправил данные в порядке A -> B -> C, то приемник их получит точно в таком же порядке временного следования.

Кстати, твой алгоритм терпит крах при кол-ве ивентов, большем или равном 64 - это ограничение для Wait-функций такого рода.


bobah   (2006-07-12 17:57:00) [42]


  Events[0]:=Self.CloseEvent;
   Events[1]:=ServSockEvent;
   CountEvents := 2;
   // Асициируем событие Accept, переводимся в неблокирующий режим
   WSAEventSelect(ServSocket,Events[1],FD_ACCEPT);

   while not Terminated do
   begin
     sync := WSAWaitForMultipleEvents(CountEvents, @Events, false, INFINITE, false);
     case sync of
       WSA_WAIT_EVENT_0  : break;   // close event
       WSA_WAIT_EVENT_0+1:          // Accept
       begin
         WSAEnumNetworkEvents(ServSocket,Events[1],@NetworkEvents);
         if NetworkEvents.lNetworkEvents and FD_ACCEPT>0 then
         if NetworkEvents.iErrorCode[FD_ACCEPT_BIT]=0 then
         begin
           NewClientSock;
         end else
         begin
           // Error := 'Ошибка подключения клиента';
         end;
       end;
       WSA_WAIT_EVENT_0+2..WSA_WAIT_EVENT_0+WSA_MAXIMUM_WAIT_EVENTS-1: // Клиентские сокеты
       begin
         ClientIndex := Sync - WSA_WAIT_EVENT_0;
         ClientSock := PClientSock(ClientConnects[ClientIndex-2]);
         WSAEnumNetworkEvents(ClientSock^.Socket,Events[ClientIndex],
           @NetworkEvents);

         if NetworkEvents.lNetworkEvents and FD_READ>0 then
         if NetworkEvents.iErrorCode[FD_READ_BIT]=0 then
         begin
           // Пришли данные, которые надо прочитать
           RecievePacket(ClientSock,ClientIndex-2);
         end else
         begin
           // Произошла ошибка. Надо сообщить о ней и завершить нить
           //CloseSocket(S);
         end;
         if NetworkEvents.lNetworkEvents and FD_CLOSE>0 then
         begin
           // Связь разорвана
           if NetworkEvents.iErrorCode[FD_CLOSE_BIT]=0 then
           begin
             // Свзяь закрыта корректно
           end else
           begin
             // Связь разорвана в результате сбоя сети
           end;
           // В любом случае надо закрыть сокет и завершить нить
           CloseClientSock(ClientIndex);
         end;
       end;
     end; // case
   end;


Для наглядности кусок кода.
Я чего-то весь запутался. Так как же обеспечить чтобы сообщения, приходящие на сервер, уходили на другие клиенты в том порядке, в котором они приходят на сервер?


Сергей М.   (2006-07-12 17:46:00) [43]


> 1)


Не обязательно.


> 2)


Нет.
Ивент сигнализирует лишь о непустомбуфере.


> Кстат и


bobah   (2006-07-12 17:35:00) [44]

1)Всё же не догнал, если есть несколько активных ивэнтов, то они будут обработаны в WSA_WAIT_EVENT_0+x в порядке согласно массиву Events? Или всё таки в порядке их наступления?

2)То есть ивэнт на рид сработает только тогда, когда всё сообщение от клиента будет в буфере? А как же разделения сообщений на пакеты?

Кстате используется протокол TCP.


Сергей М.   (2006-07-12 17:20:00) [45]


> события будут обрабатываться в том же порядке как они наступили
> или по порядку согласно массиву Events?


Да.


> далее оставшаяся часть сообщения первого клиента - такое
> может быть?


Нет, не может, если конкретный ивент ассоциирован с конкретным клиентом.


bobah   (2006-07-12 17:12:00) [46]

В частности волнует вопрос, события обрабатывютя после WSAWaitForMultipleEvents в том порядке в котором они наступили. Пример - сервер обрабатывает read от одного клиента, в это время наступило скажем три события, дале когда дело доходит до функции WSAWaitForMultipleEvents, события будут обрабатываться в том же порядке как они наступили или по порядку согласно массиву Events?
И ещё, если от сообщения одного клиента придет только часть, потом придет сообщение друго клиента, а далее оставшаяся часть сообщения первого клиента - такое может быть?

Хорошо БД - это служба, сервис какая разница, это не принципиально.


Сергей М.   (2006-07-12 17:00:00) [47]


> Как это обеспечить?


А что этому мешает ?


> три вида программ. 1 - БД


БД не является программой.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо