Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.05.01;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.004 c
15-1295136146
Palladin
2011-01-16 03:02
2011.05.01
Java 7, большие числовые константы


15-1295268013
И. Павел
2011-01-17 15:40
2011.05.01
Может ли HTML-страница сохраниться на локальной машине


1-1253191377
pesttt
2009-09-17 16:42
2011.05.01
запретить сворачивание дочерних окон при сворачивании основного


15-1294829907
Пит
2011-01-12 13:58
2011.05.01
Русские символы в Apache


2-1295729324
dik59
2011-01-22 23:48
2011.05.01
Новая серия в TChart





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский