![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как лучше реализовывать архитектуру клиент-сервер [D7, WinXP]
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 - БД
БД не является программой.