Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.05.01;
Скачать: CL | DM;

Вниз

ServerSocket , напрягает отправка ответа клиенту по номеру конне   Найти похожие ветки 

 
ZV ©   (2011-01-27 12:59) [0]

Ситуация такая – клиенты шлют сообщения на сервер для их обработки, обработка в некоторые моменты времени  происходит медленнее чем приходят запросы от клиента поэтому приходиться буферизировать запросы для дальнейшей обработки при буферизации запроса от клиента я сохраняю номер коннекта клиента для того что бы  потом знать кому отправить ответ.
Все работает нормально до  момента  когда – клиент прислал запрос, программа его сохранила и сохранила номер коннекта , запрос ждет своей  очереди, и в этот момент какой то клиент  находящейся по номеру коннекта ниже того клиента который ждет ответа  отключается, получается что теперь клиенту который ждет ответ  соответствует другой номер коннекта и когда запрос будет обработан то ответ будет отправлен по номеру коннекта сохранённому перед обработкой , получается что ответ получает не тот клиент .
Можно конечно сохранять перед обработкой  не номер коннекта  клиента, а  его IP , но тогда при отправке ответа клиенту придется перебрать все активные коннекты на соответствие нужному  IP
адресу , хорошо если их с десяток , а если будет  200, хотя если это займет  не больше 2мс  то пойдет.
Как  быть? Кто что посоветует?


 
brother ©   (2011-01-27 13:11) [1]

у меня дежаву?


 
ZV ©   (2011-01-27 13:15) [2]


> у меня дежаву?

Нет :)


 
brother ©   (2011-01-27 13:16) [3]

тогда я спокоен...


 
Anatoly Podgoretsky ©   (2011-01-27 13:47) [4]

> ZV  (27.01.2011 12:59:00)  [0]

Надо ввести понятие Сессия


 
ZV ©   (2011-01-27 13:52) [5]


> Надо ввести понятие Сессия

А это как? Где на это понятие можно посмотреть ?


 
Плохиш ©   (2011-01-27 14:03) [6]

Может всё-таки почитать теорию и технологии распределённых систем. В делфи даже есть мастера для создания нескольких вариантов таких сиатем.


 
ZV ©   (2011-01-27 14:13) [7]


> Может всё-таки почитать теорию

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


 
DiamondShark ©   (2011-01-27 14:36) [8]

А нафига вам какой-то номер клиента?
Хэндл сокета или ссылка на экземпляр класса-обёртки для сокета вполне однозначно идентифицируют клиента.

Какая вам разница, что переберать, номера, хэндлы, адреса?
В 2 мс уложится линейный перебор статыщьмильёнов простых значений.
Но в случае ссылки на объект или хэндла никакого перебора не надо вообще.


 
ZV ©   (2011-01-27 14:56) [9]


> Хэндл сокета или ссылка на экземпляр класса-обёртки для
> сокета вполне однозначно идентифицируют клиента.

Без примера я не пойму о чем идет речь.
Радует то что решение есть но жаль что я не могу понять об чем вы


> Какая вам разница, что переберать, номера, хэндлы, адреса?

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


 
Sha ©   (2011-01-27 16:38) [10]

ZV ©   (27.01.11 13:52) [5]

>> Надо ввести понятие Сессия
> А это как? Где на это понятие можно посмотреть ?

Это запись или объект, хранящие необходимую тебе информацию о соединении.
Сохраняй адрес записи или ссылку на объект.


 
Плохиш ©   (2011-01-27 16:45) [11]


> Сервер остановлен на пару дней для устранения проблемы которую
> я привел выше. По этому времени на изучение теории нет,
> надо быстро искать решение на практике. Каждый день простоя
> сервера сервера, приносит серьезные финансовые потери и
> не довольство клиентов.

Ну продолжайте ездить на своём велосипеде.


 
KSergey ©   (2011-01-27 16:48) [12]

> ZV ©   (27.01.11 14:56) [9]
> зная номер коннекта клиента

Не понятно что есть "номер коннекта клиента".
и почему он изменяется, если один из клиентов отваливается??
как устроен это самый учет коннектов сейчас?
в примерах, пожалуйста.


 
Sha ©   (2011-01-27 16:51) [13]

Телепаю, что это у него номер позиции в списке соединений


 
ZV ©   (2011-01-27 17:43) [14]


> что это у него номер позиции в списке соединений

Угу, так и есть


 
DiamondShark ©   (2011-01-27 17:44) [15]


> Телепаю, что это у него номер позиции в списке соединений

Подтверждаю приём телепатограммы.

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


 
ZV ©   (2011-01-27 17:50) [16]

Ещё вопрос. Бывает ситуация когда приемный буфер сокета содержит не верную информацию и его нужно очистить , как это сделать?
Есть что то типа ServerSocket1.Socket.Connections[0].ReceiveBuf.Clear;
На данный момент буфер очищаю считывая всю информацию из него


 
ZV ©   (2011-01-27 17:53) [17]


> В качестве быстрого устранения серьёзных финансовых потерь
> предлагаю не двигать записи в списке соединений.

Да я их не двигаю.После события Disconnect  или Connect список обновляется автоматически компонентом TServerSocket


 
Sha ©   (2011-01-27 18:03) [18]

> ZV ©   (27.01.11 17:53) [17]

[4], [8], [10]


 
KSergey ©   (2011-01-27 18:09) [19]

> ZV ©   (27.01.11 17:53) [17]
> Да я их не двигаю.После события Disconnect  или Connect
> список обновляется автоматически компонентом TServerSocket

Это речь про TServerSocket.Socket.Connections[] чтоли??
Ту так элементы здесь типа TCustomWinSocket, а там есть поле Data
В нем и храни уникальное число для каждого соединения или указатель на связанную с соединением структуру, в которой уже хранить всю необходимую уникальную информацию.


 
Slym ©   (2011-01-27 20:07) [20]

поточная модель не устроит? там никаких i, сам себе сессия, знаешь только себя и клиента...


 
ZV ©   (2011-01-27 20:33) [21]


> поточная модель не устроит? там никаких i, сам себе сессия,
>  знаешь только себя и клиента...

Устроит , а что это такое?


 
Сергей М. ©   (2011-01-27 22:22) [22]


> Бывает ситуация когда приемный буфер сокета содержит не
> верную информацию


Что значит "не верную" ?
С какой луны она туда свалилась, если партнер отправил заведомо "верную" ?
А если партнер отправил заведомо неверную-непонятную, то нафих нужно с ним вошкаться - чистить буфер приема и продолжать ждать пока он такую же очередную хрень пришлет ?
Отключить его к лешему - и всех делов ! Как это делает добрая половина приличных прикладных серверов)
Ну можно еще перед этим послать предупреждающее сообщение и следом отключиться, как это делает другая половина приличных серверов)


 
KSergey ©   (2011-01-27 22:43) [23]

> ZV ©   (27.01.11 20:33) [21]
> Устроит , а что это такое?

"Я, я свидетель! А что случилось?"


 
KSergey ©   (2011-01-27 22:44) [24]

> Сергей М. ©   (27.01.11 22:22) [22]
> Что значит "не верную" ?

Очевидно, пробел лишний.


 
ZV ©   (2011-01-27 23:01) [25]


> А если партнер отправил заведомо неверную-непонятную, то
> нафих нужно с ним вошкаться - чистить буфер приема и продолжать
> ждать пока он такую же очередную хрень пришлет ?
> Отключить его к лешему - и всех делов ! Как это делает добрая
> половина приличных прикладных серверов)

Да так все и происходит.
Если клиент начинает мутить то сервер его отключит после нескольких не правильных запросов.Но несколько раз буфер по любому чистить приходиться
поэтому и спросил может есть какая то функция чтобы очистить буфер не читая его полностью.


 
ZV ©   (2011-01-27 23:07) [26]


> Очевидно, пробел лишний.

Данные приходят криптованые . И если ключ криптования не тот то клиента после нескольких попыток обмануть сервер отключает


 
Anatoly Podgoretsky ©   (2011-01-27 23:34) [27]

> Сергей М.  (27.01.2011 22:22:22)  [22]

А третья половина вообще не хочет иметь с ним дело


 
Slym ©   (2011-01-28 06:02) [28]

ZV ©   (27.01.11 17:50) [16]
Ещё вопрос. Бывает ситуация когда приемный буфер сокета содержит не верную информацию и его нужно очистить , как это сделать?

тушить свет, рубить канаты! Exit; <-тут

поточный режим, создает отдельный поток для каждого соединения.
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Controls, Forms,ScktComp, StdCtrls;

type
 TForm1 = class(TForm)
   ServerSocket1: TServerSocket;
   Button1: TButton;
   procedure ServerSocket1GetThread(Sender: TObject;
     ClientSocket: TServerClientWinSocket;
     var SocketThread: TServerClientThread);
   procedure Button1Click(Sender: TObject);
 end;
var Form1: TForm1;

implementation
{$R *.dfm}
type
 TClientThread=class(TServerClientThread)
 protected
   procedure ClientExecute; override;
 end;

type
TPacketType=(IDasas,IDwewe,Undef);
TSign=packed array[0..1] of byte;
const
PacketSign:array[TPacketType] of TSign=((03,04),(54,140),(0,0));
PacketLen:array[TPacketType] of integer=(100,100,0);

function GetPacketType(const Sign:TSign):TPacketType;
begin
for result:=low(TPacketType) to high(TPacketType) do
  if word(PacketSign[result])=word(Sign) then
    exit;
end;

{ TClientThread }
function ReceiveBufFully(Peer:TCustomWinSocket;var Buf; Count: Integer):boolean;
var pBuf:PByte;
 s:integer;
begin
 result:=false;
 pBuf:=@Buf;
 while count>0 do
 begin
   s:=Peer.ReceiveBuf(pBuf^,Count);
   if s=0 then exit;
   inc(pBuf,s);
   dec(Count,s);
 end;
 result:=true;
end;

function SendBufFully(Peer:TCustomWinSocket;var Buf; Count: Integer):boolean;
var pBuf:PByte;
 s:integer;
begin
 result:=false;
 pBuf:=@Buf;
 while count>0 do
 begin
   s:=Peer.SendBuf(pBuf^,Count);
   if s=0 then exit;
   inc(pBuf,s);
   dec(Count,s);
 end;
 result:=true;
end;

procedure TClientThread.ClientExecute;
var
 Sign:TSign;
 PcktType:TPacketType;
 PcktLen:integer;
 Pckt:string;
begin
 while not Terminated and ClientSocket.Connected do
 begin
   if not ReceiveBufFully(ClientSocket,Sign,2) then exit;
   PcktType:=GetPacketType(Sign);
   PcktLen:=PacketLen[PcktType];
   SetLength(Pckt,PcktLen);
   if not ReceiveBufFully(ClientSocket,PChar(Pckt)^,PcktLen) then exit;
 end;
end;

procedure TForm1.ServerSocket1GetThread(Sender: TObject;
 ClientSocket: TServerClientWinSocket;
 var SocketThread: TServerClientThread);
begin
 SocketThread:=TClientThread.Create(false,ClientSocket);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 ServerSocket1.ServerType:=stThreadBlocking;
 ServerSocket1.OnGetThread:=ServerSocket1GetThread;
 ServerSocket1.Active:=true;
end;

end.


 
Сергей М. ©   (2011-01-28 10:02) [29]


> буфер по любому чистить приходиться


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

> очистить буфер не читая его полностью

Пусть в буфере на некий момент находится "полторы" прикладных дейтаграмм - "кривая" в голове очереди и пол-"прямой" следом за ней.
Ты выгреб первую, определил что она "кривая", очистил буфер и ждешь очередной дейтаграммы. В это время в буфер поступает оставшаяся половина "прямой" дейтаграммы, ты ее выгребаешь, она естественно интерпретируется как "кривая" (поскольку первую половину ты своими руками покоцал при предыдущей чистке буфера)  и посылаешь клиента в эротическое путешествие, отключая его.
И чем же, спрашивается, клиент провинился ?)


 
KSergey ©   (2011-01-28 10:10) [30]

> Сергей М. ©   (28.01.11 10:02) [29]
> И чем же, спрашивается, клиент провинился ?)

А надо было по уставу обращаться!


 
Сергей М. ©   (2011-01-28 10:40) [31]


> KSergey ©   (28.01.11 10:10) [30]


А он и обращался по уставу)
А устав гласит "В одной сессии допускается один кривой запрос, при получении повторного кривого запроса клиент получает пинок под зад"


 
Sha ©   (2011-01-28 11:00) [32]

О чем вообще речь?
В прямой программе не бывает кривых данных.


 
Плохиш ©   (2011-01-28 16:00) [33]


> Sha ©   (28.01.11 11:00) [32]
>
> О чем вообще речь?
> В прямой программе не бывает кривых данных.
>

Судя по ветке прямая программа отсутствует :-(



Страницы: 1 вся ветка

Текущий архив: 2011.05.01;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.012 c
15-1295199597
12
2011-01-16 20:39
2011.05.01
Объединенная Земля, будет ли и когда, если да?


2-1296219653
mefodiy
2011-01-28 16:00
2011.05.01
Выполнение ShellExecute


2-1296122380
ZV
2011-01-27 12:59
2011.05.01
ServerSocket , напрягает отправка ответа клиенту по номеру конне


15-1294867793
Юрий
2011-01-13 00:29
2011.05.01
С днем рождения ! 13 января 2011 четверг


15-1295538997
polkin
2011-01-20 18:56
2011.05.01
Что-то знакомоеЮ мож знаете?