Entwickler-Ecke

Internet / Netzwerk - TServerSocket - Arbeiten mit Buffern


anthoney - Sa 03.02.07 19:40
Titel: TServerSocket - Arbeiten mit Buffern
Ich habe einen kleinen Testserver geschrieben.
Dazu verwende ich die Klasse TServerSocket;
Per Firefox oder IE schicke ich eine Anfrage an den Server:
Der Server soll die Anfrage nur an den Browser zurückschicken.

Beispieltext:


Delphi-Quelltext
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:
var
  Bfr: array of byte;
  BufSize: Cardinal;


procedure TForm1.ServerSocket1ClientWrite(Sender: TObject;  Socket: TCustomWinSocket);
var
  c : char;
  i : integer;
  FileHandle: Integer;
begin
  BufSize := Socket.ReceiveLength div SizeOf(Byte);
  Bfr := nil;
  SetLength(Bfr, BufSize);
  Socket.ReceiveBuf(Pointer(Bfr)^, BufSize);

  // Speichern mit Buffer geht schief
  FileHandle := FileCreate('ClientWrite.txt');
  i := FileWrite(FileHandle, Bfr, BufSize);
  FileClose(FileHandle);

  // Speichern mit einzelnen Bytes funktioniert
  FileHandle := FileCreate('ClientWrite.txt');
  for i:=0 to BufSize-1 do begin
    FileWrite(FileHandle, bfr[i], 1);
  end;
  FileClose(FileHandle);
end;


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i : integer;
begin
  i := Socket.SendBuf(Bfr, BufSize);

  Bfr := nil;
end;

// ===============================================


Ich habe nun die folgenden zwei Fragen:
1) Das Speichern über den Buffer führt zu einem anderen Ergebenis als das Speichern Byteweise. Wo habe ich hier einen Denkfehler?

2) Socket.SendBuf(Bfr, BufSize) schickt ebenfalls nicht die Bytes, die sich in dem Buffer befindne, sondern weniger und schneidet diese ab. Warum?

Danke im Voraus

Anthoney[delphi]


Narses - Mo 05.02.07 00:52

Moin und :welcome: im Forum!

user profile iconanthoney hat folgendes geschrieben:
Dazu verwende ich die Klasse TServerSocket;
Per Firefox oder IE schicke ich eine Anfrage an den Server:
Der Server soll die Anfrage nur an den Browser zurückschicken.

Was soll das werden? :? Ein HTTP-Server? ;) Das geht zwar grundsätzlich auch mit den Sockets, aber dafür sind die nun wirklich nicht gut geeignet. Schau dir mal Suche in: Delphi-Forum, Delphi-Library TIDHTTP von den Suche in: Delphi-Forum, Delphi-Library INDY-KOMPONENTEN an, damit geht das sicher besser. :D

user profile iconanthoney hat folgendes geschrieben:
Das Speichern über den Buffer führt zu einem anderen Ergebenis als das Speichern Byteweise. Wo habe ich hier einen Denkfehler?

Du dereferenzierst den Zeiger nicht. ;) Aber ich würde das sowieso über einen String machen, das geht sehr viel eleganter, als mit einem array of Byte (ist aber grundsätzlich natürlich schon egal).


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var
  Buffer: String;

// Daten aus einer Client-Verbindung lesen und an den Absender spiegeln
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
  var
    FS: TFileStream;
begin
  Buffer := Socket.ReceiveText;
  FS := TFileStream.Create('C:\Test.txt',fmOpenWrite or fmShareDenyWrite);
  try
    FS.Seek(0,soFromEnd);
    FS.Write(PChar(Buffer)^,Length(Buffer));
  finally
    FreeAndNil(FS);
  end;
  Socket.SendText(Buffer);
end;


user profile iconanthoney hat folgendes geschrieben:
Socket.SendBuf(Bfr, BufSize) schickt ebenfalls nicht die Bytes, die sich in dem Buffer befindne, sondern weniger und schneidet diese ab. Warum?

Das zu erklären, ist leider nicht ganz einfach, weil es gleich mehrere Dinge auf einmal betrifft. :? Das Hauptproblem dürfte aber deine Annahme sein, dass der gesendete Datenblock komplett beim Empfangsereignis eingetroffen ist. Dem ist aber nicht so, es werden bei jedem Ereignis max. 8kb von der WSA abgeliefert. Daraus folgt, dass der gesendete Datenblock in 8kb-Stücken angenommen werden muss.
Weiterhin: du verwendest die Ereignisse "verkehrt rum". ;)

OnClientRead :arrow: Server soll Daten vom Client annehmen
OnClientWrite :arrow: Verbindung zum Client ist bereit für weitere Sendedaten des Servers (Achtung! Gibt hier ein Problem! Mehr Infos dazu [http://www.delphi-library.de/topic_66706.html]).

cu
Narses