Mhm, unbedingt auf jedes Paket antworten zu müssen finde ich nicht gerade optimal. Sende ich im Clienten in einer while Schleife ohne Sleep() Pakete, kommen falsche Daten an. Ich denke, der ClientSocket schafft es nicht, die ganzen Daten so schnell zu senden, der Server Part sollte denke ich für einen kleinen Test und weck vom copy pasta Code aus dem Internet soweit in Ordnung sein. Zumindest wüsste ich nicht, wo sich hier noch ein Fehler verstecken könnte. Der Client sendet die Daten sehr simpel über Socket.SendBuf(...), gibt es da ab einer gewissen Geschwindigkeit Probleme?
edit: Die Pakete sind nie größer als 100~ Bytes, ein size als Byte reichte mir also im Paket Header
Delphi-Quellcode:
procedure TServerThread.ClientExecute;
type
PClientPacket = ^TClientPacket;
TClientPacket =
packed record
ID : Byte;
Size : Byte;
end;
var
readlen, readpos: Integer;
fRequest:
Array[0..1023]
of Byte;
clientPacket: TClientPacket;
const
timeout = 30 * 1000;
CPKT_TEST = 1;
// Client-Paket 1
CPKT_TEST2 = 2;
// Client-Paket 2
begin
inherited FreeOnTerminate := true;
fSocketStream := TWinSocketStream.Create(ClientSocket, timeout);
try
while (
not Terminated)
and (ClientSocket.Connected)
do
begin
try
if (fSocketStream.WaitForData(timeout))
then
begin
readpos := 0;
FillChar(fRequest, 1024, 0);
readlen := fSocketStream.
Read(fRequest, 1024);
while (readlen - readpos > 0)
do
begin
if (readlen - readpos < SizeOf(TClientPacket))
then
begin
// kein header
break;
end;
clientPacket := PClientPacket(@fRequest[readpos]))^;
{$IFDEF DEBUG}
MessageBox(0, PChar('
packet code: ' + IntToStr(clientPacket.ID) + '
size: ' + IntToStr(clientpacket.Size)),
nil, 0);
{$ENDIF}
case clientPacket.ID
of
CPKT_TEST: ;
CPKT_TEST2: ;
else
MessageBox(0, PChar('
Ungültigen Paket Code (' + IntToStr(clientPacket.ID) + '
) empfangen!'),
nil, 0);
end;
inc(readPos, clientPacket.Size + SizeOf(TClientPacket));
end;
end;
except
on E:
Exception do
begin
ClientSocket.Close();
Terminate();
end;
end;
end;
finally
fSocketStream.Free();
end;
end;
Nach einigen Paketen wird bereits die MessageBox aufgerufen, welche mir mitteilt das ein ungültiges Paket übertragen wurde. Setze ich im Clienten ein kleines Sleep passiert dies nicht.
Der Client, welcher stupide 2 unterschiedliche Pakete in einer while Schleife sendet:
Delphi-Quellcode:
var
// paket code (1, 2), restliche grö0e, daten
buf1: Array[0..9] of Byte = (1, 8, 1, 2, 3, 4, 5, 6, 7, 8);
buf2: Array[0..7] of Byte = (2, 6, 1, 2, 3, 4, 5, 6);
procedure TForm1.Button2Click(Sender: TObject);
begin
while true do
begin
ClientSocket1.Socket.SendBuf(buf1[0], Length(buf1));
ClientSocket1.Socket.SendBuf(buf2[0], Length(buf2));
end;
end;
edit: Nach dem ich nun die Buffergröße etwas angehoben habe, klappt es wie gewünscht
Ok... mein PC friert fast ein bei der Masse an Kommunikation, aber scheint soweit sehr stabil. Bin gespannt ob der Client die Daten auch so einfach fressen wird, welche vom Server kommen. Danke nochmal Sir Rufo
edit 2: Den sendbuf Fehler habe ich auch eingesehen, ich hoffe die folgende Funktion ist so korrekt, zumindest gab es mit mehreren Clients und einer while Schleife keine Übertragungsfehler. Ich werde mich jetzt mal dransetzen und daraus eine sorgfältigere Umsetzung basteln
Delphi-Quellcode:
procedure SendPacket(pData: Pointer; iLength: Integer);
var
nSentBytes: Integer;
buffer: Array of Byte;
begin
nSentBytes := 0;
SetLength(buffer, iLength);
Move(pData^, buffer[0], iLength);
while (nSentBytes < nLength) do
begin
nSentBytes := Form1.ClientSocket1.Socket.SendBuf(buffer[nSentBytes], iLength - nSentBytes);
if (nSentBytes = SOCKET_ERROR) then
break;
end;
end;