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

Вниз

Предложите идею, как реализовать....   Найти похожие ветки 

 
Adventure   (2003-03-03 11:36) [0]

Ответы от сервера приходят в виде TCP/IP пакетов.
НО! Ответ может придти не в одном пакете, а разбит на несколько.
Причем никогда не известно, какова длина ответа.
Как организовать обработку пакетов?
Пробовал проверять на "незавершенность" данных -> не серьезно.
Сейчас попробую выталкивать пакеты в стек и после сборки всех пакетов в один массив их обрабатывать --> трудоемко.

Может у кого есть идеи или собственные разработки, поделитесь.


 
Digitman   (2003-03-03 11:50) [1]

передатчик шлет приемнику dword, содержащий размер следующего следом блока данных

приемник ждет получения dword (организовав буфер размером в sizeof(dword))

после успешного получения dword приемник организует буфер (и счетчик к нему, в который изначально записывается полученный dword) размером, указанном в полученном dword, и следом же, событие за событием OnRead(), считывает из гнезда данные размером не более того, который показывает сч-к, и записывает их в подготовленный буфер с нужным смещением отн-но начала.

Исходя из размера реально принятых данных N при каждом чтении в событии OnRead() сч-к декрементируется на N и позиция в буфере инкрементируется также на N. Как только сч-к достигнет нуля, считается, что очер.блок данных принят успешно


 
Adventure   (2003-03-03 11:58) [2]


> Digitman © (03.03.03 11:50

Забавное решение.



 
Digitman   (2003-03-03 12:06) [3]


> Adventure


и - единственно верное.

ибо - поток есть поток


 
Adventure   (2003-03-03 12:26) [4]

Ну я кажется нашел более эллегантное решение. :-)

Спасибо, за помощь.


 
Digitman   (2003-03-03 12:29) [5]

Поделись, коль нашел)


 
Adventure   (2003-03-03 12:43) [6]

Var Convey: TMemoryStream;

try
FBufferLength:=Socket.ReceiveLength;
Socket.ReceiveBuf(FBuffer,FBufferLength);
if FBuffer[0]=#0 then begin
ParseCommand;
Convey.WriteBuffer(FBuffer,FBufferLength);
end
else begin
Convey.WriteBuffer(FBuffer,FBufferLength);
ParseCommand;
end;

procedure ParseCommand;
begin
Convey.Seek(0,0);
FBufferLength:=Convey.Size;
Convey.ReadBuffer(FBuffer,FBufferLength);
// Обработка
...........................
// Обработка

if {проверка на полноту данных} then Convey.Clear;

end;


 
Digitman   (2003-03-03 13:12) [7]

1-е же, что вызывает бооольшие вопросы:

1. Где выделение памяти под FBuffer перед ReceiveBuf() ?
Значение, возвращаемое св-вом ReceiveLength() и должно являться основанием для выделения блока памяти под буфер соотв.размера (не меньшего чем ReceiveLength())

2. На основании чего ты предполагаешь, что после приема какого-то очер.фрагмента потока в какой-то момент времени 0-й байт буфера обязательно будет = #0 ? Чем ты можешь оправдать такое решение (при условии, что твой передатчик непрерывно посылает блоки данных, без ожидания от приемника некоего блока данных, подтверждающего приема и разрешающего посылку след.блока данных) ?
Такой алгоритм теоретически сможет надежно работать лишь при схеме взаимодействия между передатчиком и приемником по принципу "отправка запроса - ожидание ответа - прием ответа", но никак не при работе передатчика в режиме "запрос за запросом, друг за другом непрерывно, прием же ответа - по мере поступления"


 
dimich1978   (2003-03-03 13:33) [8]

Можно делать используя этот юнит
unit LongDataTransfer;

interface
uses ScktComp;
Type TMySProc = procedure(const S:AnsiString) of object;
function SendLongText(Socket:TCustomWinSocket; S:ansiString):boolean;
function ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :string = ""):boolean;


var
InputBuf : ansiString;
InputDataSize : LongWord;
InputReceivedSize : LongWord;

implementation
function SendLongText(Socket:TCustomWinSocket; S:ansiString):boolean;
Var TextSize:integer;
TSSig : string[4];
begin
Result:=True;
Try
If not Socket.Connected then Exit;
TextSize:=Length(S);
asm
mov EAX,TextSize;
mov dword ptr TSSig[1],EAX;
mov byte ptr TSSig[0],4;

end;
S:=String(TSSig+S);
Socket.SendBuf(Pointer(S)^,Length(S));
except Result:=False;
end;
end;

procedure FlushBuffers;
begin
InputBuf:="";
InputDataSize:=0;
InputReceivedSize:=0;
end;

function ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :ansistring = ""):boolean;
var
S:ansiString;
RDSize:LongWord;
F:String[4];
begin
Result:=True;
try
If SafeCalledStr="" then begin
RDSize:=Socket.ReceiveLength;
S:=Socket.ReceiveText;
end
else begin

S:=SafeCalledStr;
RDSize:=length(S);
end;
If (Length(InputBuf)<4) and (Length(InputBuf)>0) then begin //?????????????, ? ??? ??????
S:=InputBuf+S; //???? ?????????????? ??? ?????????
FlushBuffers; //????? ??????
end;
If InputBuf="" then
begin //????? ?????? ?????;
F:=Copy(S,0,4);
asm
mov EAX,dword ptr F[1];
mov InputDataSize,EAX;
end;

if InputDataSize=RDSize-4 then begin //???? ???? ? ??????

InputBuf:=Copy(S,5,RDSize-4); //?? ??????, ?? ???????????? ???.
MySProc(InputBuf);
FlushBuffers;
Exit;
end;
if InputDataSize<RDSize-4 then begin //????? ???????.
InputBuf:=Copy(S,5,InputDataSize);
MySProc(InputBuf);
Delete(S,1,InputDataSize+4);
FlushBuffers;
ReceiveLongText(Socket,MySProc,S);
Exit;
end;
if InputDataSize>RDSize-4 then begin //??? ?????? ????????
InputBuf:=Copy(S,5,RDSize-4); //???????? ??????
InputReceivedSize:=RDSize-4;
end;
end
else begin //????? ?????? ?? ????
//InputBuf:=
If RDSize+InputReceivedSize=InputDataSize then
begin //???????? ?????????
InputBuf:=InputBuf+Copy(S,0,RDSize); //???????? ???????
MySProc(InputBuf); //? ??????, ??????
FlushBuffers; // ? ?????? ?????? ???
Exit;
end;
If RDSize+InputReceivedSize<InputDataSize then // ????????
begin //?????????
InputBuf:=InputBuf+Copy(S,0,RDSize); //????????
InputReceivedSize:=InputReceivedSize+RDSize;
Exit;
end;
If RDSize+InputReceivedSize>InputDataSize then //???????? ????????
begin // ?? ? ?????? ???? ??? ?????? - ???????.
InputBuf:=InputBuf+Copy(S,0,InputDataSize-InputReceivedSize);
MySProc(InputBuf);
Delete(S,1,InputDataSize-InputReceivedSize);
FlushBuffers;
ReceiveLongText(Socket,MySProc,S);
end;
end;
except Result:=False;
end;
end;

end.

Пример использования:
.....
Procedure DataProcessing(S:String); //Эта процедура будет обрабатывать
begin //полученные данные, и
ShowMessage(S); //автоматически вызывается каждый
end; //при получении нового блока данных.

//Процедура отправки - по нажатию кнопки отправляем через компонент
//ClientSocket три строки.
procedure TForm1.Button1Click(Sender: TObject);
begin
SendLongText(ClientSocket.Socket,"Первая строчка!");
SendLongText(ClientSocket.Socket,"Вторая строчка!");
SendLongText(ClientSocket.Socket,"Третья строчка! Все три показаны по отдельности!!!");
end;

//Процедура ServerSocket OnClientRead содержит одну строчку
//вызова ReceiveLongText, передавая ей в качесте параметра
//имя вашей процедуры обработки.
procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
ReceiveLongText(Socket,DataProcessing);
end;



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

Форум: "Сети";
Текущий архив: 2003.04.24;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.007 c
6-77069
chum
2003-03-01 19:51
2003.04.24
Работа с HTTP средствами WinApi


1-77006
Лана Розанова
2003-04-14 07:35
2003.04.24
MSOffice


3-76860
Leviathan
2003-04-07 21:07
2003.04.24
Добавление записи через TQuery


4-77221
bobo
2003-02-26 10:31
2003.04.24
Кто выше


1-77029
Evg12
2003-04-14 14:54
2003.04.24
Как выполнить функцию или процедуру имя которой в переменной





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский