Autor Beitrag
Die Brotmafia
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 110

Win XP Suse Linux 9.3
Delphi 7 Enterprise, Delphi 2005
BeitragVerfasst: Mi 25.01.06 19:13 
Also, ich will keine Anleitung oder sowas, nur ne erklärung um die sache zu verstehen!

Hab da ne kleine Anwendung, nen TServerSocket und nen TClientSocket.

ClientSocket Sendet Stream:

ausblenden 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:
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var text: string;
    OpenFile: PChar;
    FStream: TFileStream;
    StreamPath: string;
begin
 text:=Socket.ReceiveText;

 if copy(text,0,7)='GetFile' then begin
   try
    StreamPath:=copy(text,8,length(text));
     FStream:=TFileStream.Create(StreamPath, fmOpenRead);
      Socket.SendText('Size' + inttostr (FStream.Size));
       sleep(100);
       finally
        Socket.SendStream(FStream);
   end;
 end;

  if text='FileThere' then begin
   FStream.Free;
  end;



Danach:

ServerSocket empfängt:

ausblenden volle Höhe 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:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var text: string;
    Buffer: array[0..4096of Byte;
    FileGroesse: integer;
    FileStream: TFileStream;
    pBuffer: pointer;
    AlreadyReceived: integer;
    SizeofBuffer: integer;
begin
 text:=Socket.ReceiveText;

   if copy(text,0,4)='Size' then begin
    try
     FileGroesse:=strtoint(copy(text,5,length(text)));
      FileStream:=TFileStream.Create('C:\test2.txt', fmCreate or fmOpenWrite);
       finally
        try
         repeat
          pBuffer:=@Buffer;
          SizeofBuffer:=Socket.ReceiveBuf(pBuffer^, 4096);
          FileStream.Write(pBuffer^, SizeofBuffer);
          Socket.Sendtext(InttoStr(AlreadyReceived));
           until
            FileGroesse=FileStream.Size;
             finally
              Serversocket1.Socket.Connections[SelectedUser].SendText('FileThere');
               Filestream.Free;
           end;
       end;
   end;
end;



Also funktionieren tut das ganze ja wunderbar, nur weis ich anscheinend nicht so recht was ich da tue.

Hab ein paar fragen zu ein paar stellen im code:

pBuffer:=@Buffer; wozu braucht man den Buffer?

SizeofBuffer:=Socket.ReceiveBuf(pBuffer^, 4096); Warum pBuffer und warum die Zahl 4096?
Warum nicht z.B. 5055?

FileStream.Write(pBuffer^, SizeofBuffer); Wie funktioniert das? Warum bruacht man
da den Buffer und was sagt das
SizeofBuffer?

Den rest vom Server versteh ich, nun der client:

Da versteh ich alles einigermaßen, ist der code da ok oder muss man da was optimieren?


Danke!!

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 26.01.06 00:54 
Moin!

user profile iconDie Brotmafia hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
 text:=Socket.ReceiveText;

 if copy(text,0,7)='GetFile' then begin
  try
    StreamPath:=copy(text,8,length(text));

Wer sagt denn, dass copy(text,8,length(text)) tatsächlich nur den Dateinamen liefert und nicht noch etwas vom nächsten Text, den der Server sendet? In diesem FAQ-Beitrag ist genau erklärt, warum das nicht zuverlässig funktioniert. 8)
user profile iconDie Brotmafia hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
      Socket.SendText('Size' + inttostr (FStream.Size));
       sleep(100);

Wieder das gleiche: verlass dich nicht auf das Ereignissystem, das ist nicht sicher. Siehe oben! Dann noch die interessante Konstruktion mit dem try-finally-SendStream... :wink: also du versuchst den Dateinamen zu empfangen, aber sendest in jedem Fall den Stream, auch wenn du ihn gar nicht aufgemacht hast... :gruebel: ob das mal so im Sinne des Erfinders ist... :|
user profile iconDie Brotmafia hat folgendes geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
if text='FileThere' then begin
   FStream.Free;
  end;

Wenn dir der Server mittem im Stream-Senden (z.B. weil die Datei ziemlich gross ist) den Text "FileThere" sendest, machst du den Stream zu - und kriegst ne fette Exception... weil der Socket noch versucht zu lesen/senden... :gruebel:
user profile iconDie Brotmafia hat folgendes geschrieben:

ServerSocket empfängt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
text:=Socket.ReceiveText;

   if copy(text,0,4)='Size' then begin
    try
     FileGroesse:=strtoint(copy(text,5,length(text)));

Wie oben, was ist, wenn da mehr im Buffer liegt... und auch wieder die interessante try-finally-Konstruktion: wenn das Anlegen des Streams nicht klappt, wird auf jeden Fall reingeschrieben... :gruebel: in einen Stream, der gar nicht existiert... :wink:
user profile iconDie Brotmafia hat folgendes geschrieben:
Also funktionieren tut das ganze ja wunderbar, nur weis ich anscheinend nicht so recht was ich da tue.

Tja, was soll ich dazu sagen; ich halte das für mehr als zweifelhaft, ob das so sauber funktioniert. Sagen wir mal lieber so, es hat bei dir bisher noch nicht nicht funktioniert, mehr wirst du nicht behaupten können, da der Code ganz klar unsicher ist. :wink:
user profile iconDie Brotmafia hat folgendes geschrieben:
pBuffer:=@Buffer; wozu braucht man den Buffer?

Das ist nicht der Buffer, sondern ein Zeiger darauf, der Buffer ist das array. Du mußt die Daten, die aus dem Socket kommen, doch irgendwo hintun, dann kannst du das erst in den Stream schreiben.
user profile iconDie Brotmafia hat folgendes geschrieben:
SizeofBuffer:=Socket.ReceiveBuf(pBuffer^, 4096); Warum pBuffer und warum die Zahl 4096?
Warum nicht z.B. 5055?

S.o., ist der Zeiger auf den Buffer; 4096 (=4kb) ist willkürlich, du kannst natürlich auch 5055 Bytes nehmen, aber weil Buffergrößen in Zweierpotenzen effektiver verarbeitet werden (weil kein Überhang), nimmt man natürlich "glatte" Zahlen. :wink:
user profile iconDie Brotmafia hat folgendes geschrieben:
FileStream.Write(pBuffer^, SizeofBuffer); Wie funktioniert das? Warum bruacht man da den Buffer und was sagt das SizeofBuffer?

Du hast die Daten in den Buffer gelesen, jetzt willst du sie in den Stream schreiben, irgendwoher muss der Stream doch wissen, wo die Daten sind -> im Buffer. :wink: Hausaufgabe: übersetze "size of buffer" ins deutsche... :mrgreen:
user profile iconDie Brotmafia hat folgendes geschrieben:
Da versteh ich alles einigermaßen, ist der code da ok oder muss man da was optimieren?

Der war gut, du mußt die Fehler entfernen, nicht optimieren... :wink: Schau dir mal genau das Tutorial an, damit du einen Plan von einem Protokoll bekommst; danach kannst du dich um binäre Protokolle bemühen, aber so wird das nix. :wink: Sorry, ist nicht wertend, nur ehrlich.

cu
Narses


Zuletzt bearbeitet von Narses am Mi 13.09.06 15:14, insgesamt 1-mal bearbeitet
Die Brotmafia Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 110

Win XP Suse Linux 9.3
Delphi 7 Enterprise, Delphi 2005
BeitragVerfasst: Do 26.01.06 17:59 
Ok, ich werd mir jetzt mal dein Tutorial vornehmen, den Chat da proggen und schauen wie's geht ;-)


Danke aber!