Autor Beitrag
Jakob Schöttl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 07.09.06 13:43 
Hallo,
ich mach grad ein programm, das Dateien über eine Socketverbindung schicken soll.
Genauer gesagt:
ausblenden Delphi-Quelltext
1:
2:
Image1.Picture.Bitmap.SaveToStream(WinSocketStream);
ServerSocket1.Socket.SendStream(WinSocketStream);


Jetzt soll natürlich ClientSocket1 den Stream empfangen, bloß ich finde nicht die richtige Methode!

Für SendText -> ReceiveText
Für SendBuf -> ReceiveBuf

Für SendStream -> ?

Hoffentlich könnt ihr mir helfen!
Danke schon mal
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 07.09.06 14:29 
Moin!

user profile iconbokaj hat folgendes geschrieben:
Jetzt soll natürlich ClientSocket1 den Stream empfangen, bloß ich finde nicht die richtige Methode!

Für SendText -> ReceiveText
Für SendBuf -> ReceiveBuf

Für SendStream -> ?

Es gibt keine Stream-Empfangsmethode, weil diese ja nicht wissen kann, wie groß der Datenblock ist, der da empfangen werden soll. ;)

Beim Senden wird intern .SendStream auf wiederholte .SendBuf-Aufrufe runtergebrochen. Fazit: Du mußt die Daten mit .ReceiveBuf annehmen und selbst rausfinden, was davon zu deinem Stream gehört. :D

Daraus folgt: du brauchst ein Protokoll (wie auch immer das aussieht, ist ein anderes Problem). Ein Beispiel, wie man ein Protokoll entwickelt, findest du hier.

cu
Narses

PS: Den WinSocketStream brauchst du nur für blocking-socket-calls, du kannst ruhig "normale" Streams nehmen, wenn du non-blocking arbeitest. ;)

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 07.09.06 16:16 
Danke Narses, in Sachen Netzwerk ist auf dich immer Verlass!
In meinem Fall brauche ich (glaub ich) gar kein Protokoll, weil der Server immer eine gleichgroße bmp-Datei an den Client schickt.

Wenn aber der Server mit SendStream den Stream schickt, dann kommt beim Client kein OnRead-Ereignis. Wie kann ich also dann ReceivedBuf abfragen?

Liegt es vllt daran, dass beim Server steht
ausblenden Delphi-Quelltext
1:
2:
3:
ServerSocket1.Socket.SendStream(Stream);
//und nicht
ServerSocket1.Socket.Connections[0].SendStream(Stream);

??
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 07.09.06 16:57 
Moin!

user profile iconbokaj hat folgendes geschrieben:
In meinem Fall brauche ich (glaub ich) gar kein Protokoll, weil der Server immer eine gleichgroße bmp-Datei an den Client schickt.

Ob du ein Protokoll brauchst oder nicht, mußt du natürlich selbst entscheiden. Wenn du schon vorher weißt, wie groß der Stream ist, den du empfangen willst, dann geht das natürlich auch ohne. Wenn allerdings die Größe variabel ist (oder sich später mal ändert), dann wäre ein Protokoll-Ansatz sicherlich die bessere Wahl.

user profile iconbokaj hat folgendes geschrieben:
Wenn aber der Server mit SendStream den Stream schickt, dann kommt beim Client kein OnRead-Ereignis.

Dann machst du was falsch, es muss ein Ereignis ausgelöst werden (s.u.).

user profile iconbokaj hat folgendes geschrieben:
Liegt es vllt daran, dass beim Server steht
ausblenden Delphi-Quelltext
1:
2:
3:
ServerSocket1.Socket.SendStream(Stream);
//und nicht
ServerSocket1.Socket.Connections[0].SendStream(Stream);

??

Ja, du mußt an die Connections aus dem Array des Servers senden, da hängen die Clients dran. ;) Alternativ kannst du auch den Socket: TCustomWinSocket-Parameter aus der Ereignisprozedur nehmen, das ist garantiert immer die Richtige Verbindung. Siehe auch FAQ-Beitrag.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 07.09.06 17:15 
Narses, vllt siehst du ja sofort, was ich falsch mache: :cry:

Beim Server:
Zuerst lese ich aus der Verbindung, und schicke gleich anschließen den Stream zurück. Beide ShowMessage tauchen auf, und ich klicke ok.
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:
24:
procedure TMainForm.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var Picture: TPicture;
    s: string;
    n: integer;
begin
  Picture := TPicture.Create;
  Stream := TMemoryStream.Create;
  try
    ShowMessage('Client Read');
    s := Socket.ReceiveText;
    if s = 'SendScreenShot' then begin
      MakeScreenShot(Picture.Bitmap);
      //Image1.Picture := Picture; //Funktioniert
      Picture.Bitmap.SaveToStream(Stream);
      //Picture.Bitmap.SaveToFile('c:\win98\profiles\jakob\eigene dateien\snap1.bmp'); //Funktioniert
      ShowMessage('Stream wird verschickt');
      Socket.SendStream(Stream);
    end;
  finally
    Picture.Free;
    //Stream.Free;
  end;
end;

Dann beim Client:
Die ShowMessage taucht nicht auf, und auch bei einem Haltepunkt bleibt er nicht stehen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TMainForm.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var Stream: TMemoryStream;
begin
  ShowMessage('Read');
  Stream := TMemoryStream.Create;
  try
    showMessage(s);
  finally
    Stream.Free;
  end;
end;
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 07.09.06 17:34 
Moin!

user profile iconbokaj hat folgendes geschrieben:
Narses, vllt siehst du ja sofort, was ich falsch mache: :cry:

Der Fehler ist vermutlich hier:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
      Picture.Bitmap.SaveToStream(Stream);
      ShowMessage('Stream wird verschickt');
      Stream.Position := 0; // an den Anfang des Streams, sonst wird nix gesendet. ;)
      Socket.SendStream(Stream);
    end;

Allerdings würde ich da noch andere Dinge ändern:
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:
24:
25:
26:
procedure TMainForm.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Bitmap: TBitmap;
  s: string;
  n: integer;
begin
  Bitmap := TBitmap.Create;
  Stream := TMemoryStream.Create;
  try
    ShowMessage('Client Read');
    s := Socket.ReceiveText;
    if (s = 'SendScreenShot'then begin // wer sagt denn, dass hier nur der Text ankommt? s.u.
      MakeScreenShot(Bitmap);
      // Image1.Picture.Bitmap.Assign(Bitmap); // wenn schon, dann so, aber nicht den Zeiger zuweisen!
      Bitmap.SaveToStream(Stream);
      // Bitmap.SaveToFile('c:\win98\profiles\jakob\eigene dateien\snap1.bmp');
      ShowMessage('Stream wird verschickt');
      Stream.Position := 0// an den Anfang des Streams, sonst wird nix gesendet. ;)
      Socket.SendStream(Stream); // der Socket wird Eigentümer des Streams und gibt ihn frei
    end;
  finally
    Bitmap.Free;
    // Stream.Free; // das darfst du auf keinen Fall machen, weil .SendStream Eigentümer wird!
  end;
end;

Wenn ich mir so den Code ansehe, dann machst du einen klassischen Fehler: du verläßt dich auf die Ereignisse als Signalisierung. Das ist allgemein ein Fehler, siehe FAQ-Beitrag. ;)

Und da du Befehle und Daten in deiner Übertragung hast, würde ich dir hiermit GANZ DRINGEND ein Protokoll ans Herz legen. Schau mal in das Tut, im Kapitel 8 wird eine Bitmap übertragen, zusätzlich zum Chatten, das ist genau das, was du hier auch machen willst. ;) Sorry, aber die meisten Probleme laufen einfach immer wieder darauf hinaus, dass ein Protokoll die Lösung ist; nur die Problemstellung variiert leicht... :D

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 07.09.06 17:51 
Einarbeiten muss ich mich sowieso, dann mach ichs genau, so wie dus im Tutorial empfiehlst, denn jetzt kommt zwar das Ereignis OnRead beim Client, aber auch eine Exception beim Server: ESocketError, Meldung 'Asynchroner Socket-Fehler'.

Ich dachte es kann nicht so schwer sein, eine Datei übers Netzwerk zu verschicken...
Es gibt da keinen einfachen Befehl, oder so?
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 07.09.06 18:00 
Moin!

user profile iconbokaj hat folgendes geschrieben:
Ich dachte es kann nicht so schwer sein, eine Datei übers Netzwerk zu verschicken...
Es gibt da keinen einfachen Befehl, oder so?

Wenn ich einen kennen würde, hätte ich dann das Tut geschrieben? :mrgreen:

Aber sagen wir mal so: wenn du einen findest, sag mir bescheid! ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakob Schöttl Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 929
Erhaltene Danke: 1


Delphi 7 Professional
BeitragVerfasst: Do 07.09.06 18:05 
OK, Danke trotzdem für deine Hilfe Narses!
Ich schaff das schon :roll: - Vielleicht, wenn ich genügend nerve habe ...
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mo 09.10.06 21:24 
Moin!

Ich habe den Thread bzw. die Frage mal eingedampft in die FAQ gestellt. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.