-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLongDataTransfer.pas
More file actions
182 lines (167 loc) · 6.39 KB
/
Copy pathLongDataTransfer.pas
File metadata and controls
182 lines (167 loc) · 6.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
{ **** UBPFD *********** by delphibase.endimus.com ****
>> Ïðîöåäóðû ïåðåäà÷è è ïðèåìà äëèííûõ áëîêîâ äàííûõ, ñ ó÷åòîì ôðàãìåíòàöèè
è âîçìîæíîé ñëåïêè ïàêåòîâ. Íà êîìïîíåíòû TServerSocket,TClientSocket ..SendText
Äàííàÿ ìîäóëü ñîäåðæèò ôóíêöèè, êîòîðûå ïîçâîëÿåò ïðèíèìàòü è îòïðàâëÿòü äëèííûå áëîêè äàííûõ.
 êîä âñòðåíà àâòîìàòè÷åñêàÿ îáðàáîòêà ôðàãìåíòàöèè è ñëåïêè ïàêåòîâ.
Äàííûå ïðîöåëóðû ïðåäíàçíà÷åíû äëÿ ïåðåäà÷è òåêñòîâûõ ñòðîê, è èñïîëüçóþò
ìåòîäû SendText, ReciveText TCustomSocket è ïðåäíàçíà÷åíû äëÿ èñïîëüçîâàíèÿ
ñ êîìïîíåíòàìè TClientSocket, TServerSocket è äðóãèõ ïðîèçâîäíûõ îò TCustomSocket.
Äàííûå ðåøåíèå îòëè÷àåòñÿ ïðîñòîòîé èñïîëüçîâàíèÿ, ñêîðîñòüþ îáðàáîòêè è íàäåæíîñòüþ:
òåñòèðîâàëîñü ïîñûëêîé áëîêîâ äàííûõ ðàçìåðîì 1-16000, áûëî îáðàáîòàíî 15100 áëîêîâ äàííûõ.
Ïîñëåäóþùåå ñðàâíåíèå îòïðàâëåííõ è ïîëó÷åííûõ äàííûõ ïîêàçàëî îòñóòâèå êàêèõ ëèáî
îøèáîê ïðè ïåðåäà÷è, ñáîðêè è ôðàãìåíòàöèè äàííûõ.
Ïåðåä èñïîëüçîâàíèåì íóæíî ïðèãîòîâèòü ïîëüçîâàòåëüñêóþ ïðîöåäóðó, êîòîðàÿ
áóäåò âûçûâàòüñÿ êàæäûé ðàç, êîãäà ïîëó÷åí î÷åðåäíîé ÁËÎÊ äàííûõ. Äàííàÿ ïðîöåäóðà
äîëæíà èìåòü ÎÄÈÍ âõîäíîé ïàðàìåòð òèïà STRING:
procedure SomeUserProc(S:String);
begin
....
end;
Ìîäóëü ñîäåðæèò 3 ôóíêöèè, èç êîòîðûõ ïîëüçüçîâàòåëþ íóæíû òîëüêî 2
function SendLongText(Socket:TCustomWinSocket; S:String):boolean;
function ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :string = ''):boolean;
Ôóíöèÿ SendText ñëóæèò äëÿ îòïðàâêè ïàêåòîâ.  êà÷åñòâå ïàðàìåòðîâ åé ïåðäàåòñÿ
îáúåêò TCustomWinSocket (íàïðèìåð ýòî ClientSocket.Socket) è ñîáñòâåííî
îòïðàâëÿåìÿ ñòðîêà S (ShortString,AnsiString,WideString).
 ñëó÷àå óñïåøíîé îòïðàâêè ôóíêöèÿ âîçâðàùàåò true, èíà÷å false.
Äëÿ îáðàáîòêè èñïîëüçóéòå GetLastError().
function ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :string = ''):boolean;
Èñïîëüçóåòñÿ äëÿ ïîëó÷åíèÿ. Äàííàõ ôóíöèÿ äîëæíà áûòü âûçâàíà â ñîáûòèè On*Read êîìïîíåíòà.
 êà÷åñòâå ïàðàìåòðîâ íåîáõîäèìî ïåðåäàòü TCustomWinSocket (íàïðèìåð ServerSocket.Socket) è èìÿ ïðîöåäóðû,
íàçíà÷åííîé äëÿ îáðàáîòêè äàííûõ (íàïðèìåð, ðàíåå ïðèãîòîâëåííàÿ SomeUserProc).
Òðåòèé ïàðàìåòð ÇÀÏÎËÍßÒÜ ÍÅ ÑËÅÄÓÅÒ!!!
Ïðîöåäóðà FlushBuffers ÿâëÿåòñÿ âíóòðåííåé è î÷èùàåò áóôåð ïðèåìà,
è íàïðÿìóþ ïîëüçîâàòåëåì âûçûâàòüñÿ íå äîëæíà.
Çàâèñèìîñòè: ScktComp;
Àâòîð: Subfire, subfire@mail.ru, ICQ:55161852, Ñàíêò-Ïåòåðáóðã
Copyright: Åãîðîâ Âèêòîð aka Subfire
Äàòà: 2 îêòÿáðÿ 2002 ã.
***************************************************** }
unit LongDataTransfer;
interface
uses Windows, SysUtils, Classes, ScktComp, comm_info, comm_data;
type
TMySProc = procedure(const S: String);
function SendLongText(Socket: TCustomWinSocket; S: string): boolean;
function ReceiveLongText(Socket: TCustomWinSocket; MySProc: TMySProc;
SafeCalledStr: AnsiString = ''): boolean;
procedure FlushBuffers;
var
InputBuf: AnsiString;
InputDataSize: LongWord;
InputReceivedSize: LongWord;
implementation
function SendLongText(Socket: TCustomWinSocket; S: string): boolean;
var
TextSize: DWord;
SendStream: TMemoryStream;
begin
Result := True;
try
if not Socket.Connected then
Exit;
TextSize := Length(S);
SendStream := TMemoryStream.Create;
SendStream.WriteBuffer(TextSize, 4);
SendStream.WriteBuffer(PChar(S)^, TextSize * 2);
SendStream.Seek(0, soFromBeginning);
Socket.SendStream(SendStream);
except Result := False;
end;
end;
procedure FlushBuffers;
begin
InputBuf := '';
InputDataSize := 0;
InputReceivedSize := 0;
end;
procedure CallSFunc(MySProc: TMySProc; Str: AnsiString); inline;
var
CallStr: String;
begin
SetLength(CallStr, Length(Str) div 2);
CopyMemory(@CallStr[1], @Str[1], Length(Str));
MySProc(CallStr);
end;
function ReceiveLongText(Socket:TCustomWinSocket;MySProc:TMySProc;SafeCalledStr :AnsiString = ''):boolean;
var
S:AnsiString;
RDSize:LongWord;
begin
Result:=True;
try
If SafeCalledStr='' then begin
RDSize:=Socket.ReceiveLength;
SetLength(S, RDSize);
Socket.ReceiveBuf(S[1], RDSize);
end
else begin
S:=SafeCalledStr;
RDSize:=length(S);
end;
//PCorePlugin^.WriteLog(file_debug, 'Packet: '+IntToStr(RDSize)+' '+IntToStr(InputReceivedSize)+' '+IntToStr(InputDataSize));
if InputDataSize > 500000 then
PCorePlugin^.WriteLog(file_debug, 'Warning: Packet: '+IntToStr(RDSize)+' '+IntToStr(InputReceivedSize)+' '+IntToStr(InputDataSize));
If (Length(InputBuf)>0) and (InputDataSize = 0) then begin //Êîððåêòèðîâêà, â òîì ñëó÷àå
S:=InputBuf+S; //åñëè ôðàãìåíòèðîâàí ñàì çàãîëîâîê
FlushBuffers; //áëîêà äàííûõ
RDSize:=length(S);
end;
If InputDataSize=0 then
begin //Ñàìûé ïåðâûé ïàêåò;
// Ôðàãìåíò çàãîëîâêà
if Length(S) < 4 then
begin
InputBuf := S;
Exit;
end;
CopyMemory(@InputDataSize, @S[1], 4);
InputDataSize := InputDataSize * 2;
//MessageBox(0, PChar('First: '+IntToStr(RDSize)+' '+IntToStr(InputReceivedSize)+' '+IntToStr(InputDataSize)), '', 0);
if InputDataSize=RDSize-4 then begin //Îäèí áëîê â ïàêåòå
InputBuf:=Copy(S,5,RDSize-4); //íè ñëåïêè, íè ôðàãìåíòàöèè íåò.
CallSFunc(MySProc, InputBuf);
FlushBuffers;
Exit;
end;
if InputDataSize<RDSize-4 then begin //Ïàêåò ñëåïëåí.
InputBuf:=Copy(S,5,InputDataSize);
CallSFunc(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,1,RDSize); //ôðàãìåíò öåëèêîì
CallSFunc(MySProc, InputBuf); //â ïàêåòå, äàííûõ
FlushBuffers; // â ïàêåòå áîëüøå íåò
Exit;
end;
If RDSize+InputReceivedSize<InputDataSize then // Ïîëó÷èëè
begin //î÷åðåäíîé
InputBuf:=InputBuf+Copy(S,1,RDSize); //ôðàãìåíò
InputReceivedSize:=InputReceivedSize+RDSize;
Exit;
end;
If RDSize+InputReceivedSize>InputDataSize then //Ïîëåäíèé ôðàãìåíò
begin // íî â ïàêåòå åñòü åùå äàííûå - ñëåïëåí.
InputBuf:=InputBuf+Copy(S,1,InputDataSize-InputReceivedSize);
CallSFunc(MySProc, InputBuf);
Delete(S,1,InputDataSize-InputReceivedSize);
FlushBuffers;
ReceiveLongText(Socket,MySProc,S);
end;
end;
except Result := false;//MessageBox(0, PChar(IntToStr(RDSize)+' '+IntToStr(InputReceivedSize)+' '+IntToStr(InputDataSize)), '', 0);//Result:=False;
end;
end;
end.