Форум: "Потрепаться";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];
ВнизДва вопроса по коду кто знает помогите Найти похожие ветки
← →
Программер_ (2004-09-19 14:58) [0]1.Что значить выделый франмент асмовского кода и как его можно записать без асма
2.Если этот код применять для ServerSocket`а то , нужно ли создавать дин массив что бы у каждого клиента был свой буффер?
unit LongDataTransfer;
interface
uses ScktComp;
TYPE TMySProc = PROCEDURE (CONST S:AnsiString);
FUNCTION SendLongText(Socket:TCustomWinSocket; S:STRING): boolean;
FUNCTION ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :STRING =
""): boolean;
PROCEDURE FlushBuffers;
VAR
InputBuf : STRING;
InputDataSize : LongWord;
InputReceivedSize : LongWord;
implementation
FUNCTION SendLongText(Socket:TCustomWinSocket; S:STRING): 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 :STRING =""): boolean;
VAR
S: STRING;
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.
← →
cyborg © (2004-09-19 15:33) [1]
> asm
> mov EAX,TextSize;
> mov dword ptr TSSig[1],EAX;
> mov byte ptr TSSig[0],4;
>
> END;
Это значит подсунуть в строку в 4 символа значение длины строки, а затем установить длину строки в 4.
Что-ти типа этого:
Longint(TSSig[1]):=TextSize;
TSSig[0]:=4;
← →
cyborg © (2004-09-19 15:54) [2]В общем сделай так:
FUNCTION SendLongText(Var Socket:TCustomWinSocket; S:STRING): boolean;
VAR
Buf : Pointer;
TextSize: integer;
BEGIN
Result := False;
IF NOT Socket.Connected THEN Exit;
Try
TextSize := Length(S);
GetMem(Buf,TextSize+4);
Longint(Buf^):=TextSize;
Move(S[1],Pointer(Longint(Buf)+4),TextSize);
Socket.SendBuf(Buf^,TextSize+4);
Result:=True;
Finally
FreeMem(Buf,TextSize+4);
End;
END;
В браузере набирал, возможны ошибки. Желательно ещё контролировать сколько байт отослано, оставшееся досылать.
← →
cyborg © (2004-09-19 15:56) [3]Чего-то не помню порядок параметров в Move или
Move(S[1],Pointer(Longint(Buf)+4),TextSize);
или
Move(Pointer(Longint(Buf)+4),S[1],TextSize);
нужно.
← →
Программер_ (2004-09-19 17:27) [4]cyborg © (19.09.04 15:56) [3]
Спасибо , а на вопрос 2 есть соображения?
← →
Программер_ (2004-09-20 10:52) [5]ау
← →
Digitman © (2004-09-20 11:04) [6]
> Если этот код применять для ServerSocket`а то , нужно ли
> создавать дин массив что бы у каждого клиента был свой буффер?
этот или не этот код - без разницы : с каждым клиентом должен быть ассоциирован буфер приема и буфер передачи ... а в каком виде фигурируют эти буферы - в виде дин.массива или в виде чего-то еще - так же без разницы
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.10.10;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.035 c