![]() |
ClientSocket
Hallo zusammen,
ich befasse mich jetzt schon den ganzen Tag mit der Komponente ClientSocket, komme allerdings auf keinen grünen Zweig. Im Prinzip ist es ganz simpel, eine Prozedur soll mit dem ClientSocket mehrere Einträge einer Liste abfragen und die Antwort in einer anderen Liste speichern.
Code:
Wenn ich das richtig sehe habe ich hier aber mindestens zwei Fehler. Der Text wird gesendet bevor der Socket überhaupt connected ist und es wird nicht auf das Ergebnis gewartet.
var response:string;
ClientSocket1.open; for I : = 0 to liste.count-1 do begin Clientsocket1.Socket.SendText(liste.strings[i]); response:=Clientsocket1.Socket.ReceiveText; liste2.add(response); end; ClientSocket1.close; Kann mir jemand einen vernünftigen Ansatz liefern? Ich bin offenbar nicht fähig dazu :( Vielen Dank! LG, Chris |
AW: ClientSocket
Hier gibt es ein nettes Tutorial, wo ein Chat mit den Sockets implementiert wurde, das könnte für dich ein Einstieg sein.
![]() Hier ein weiteres, wobei es da unter den weiterführenden Link erst richtig interessant wird, wo es um Protokolle geht: ![]() |
AW: ClientSocket
Hallo Ralph,
vielen Dank für deine schnelle Antwort. Mein Problem ist leider, dass in diesen Tutorials immer das Onread Ereignis des ClientSockets genutzt wird. In meiner gezeigten Routine kann ich dann denn empfangenen Text aber garnicht speichern da das Ereignis ja quasi außerhalb dieser Prozedur liegt. Ist es so wie ich mir das vorstelle überhaupt möglich? LG, Chris |
AW: ClientSocket
Liste der Anhänge anzeigen (Anzahl: 1)
Diese Uraltkomponente hatte ich ewig nicht mehr in der Hand, die Blockingmethode mit Streams bekomme ich auf die schnelle scheinbar nicht zum laufen ... vielleicht hilft Dir folgende Kapselung für das erste ...
Delphi-Quellcode:
unit ClientSocketBlocking;
// 2012 by Thomas Wassermann interface uses Windows, Messages, SysUtils, ScktComp, Classes,Forms; Type TOldClientSocketTest = Class Private FCs: TClientSocket; FSL: TStringList; FHost:String; FContent:String; FReady:Boolean; procedure MyDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure MyOnRead(Sender: TObject; Socket: TCustomWinSocket); procedure MyOnWrite(Sender: TObject; Socket: TCustomWinSocket); protected Constructor Create(Const AUrl: String; Port: Integer = 80); Destructor Destroy ; public Class Function GetPage(Const AUrl: String; Port: Integer = 80):String; End; implementation { TOldClientSocketTest } destructor TOldClientSocketTest.Destroy; begin FSL.Free; FCS.Free; end; class function TOldClientSocketTest.GetPage(const AUrl: String; Port: Integer=80): String; begin With Create(AUrl,Port) do begin Result := FSL.Text; Destroy; end; end; procedure TOldClientSocketTest.MyDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin FReady := true; end; procedure TOldClientSocketTest.MyOnRead(Sender: TObject; Socket: TCustomWinSocket); begin FSL.Add(TClientSocket(Sender).Socket.ReceiveText); end; procedure TOldClientSocketTest.MyOnWrite(Sender: TObject; Socket: TCustomWinSocket); begin Socket.SendText('GET ' + FContent + ' HTTP/1.0' + #13#10#13#10); end; constructor TOldClientSocketTest.Create(const AUrl: String; Port: Integer); var i:Integer; begin FSL := TStringList.Create; FCs := TClientSocket.Create(nil); try if pos('http://',Lowercase(AUrl))>0 then FHost := Copy(Aurl,8,Length(Aurl)) else FHost :=(AUrl); i := Pos('/',FHost); if i>0 then begin FContent := Copy(FHost,i,length(FHost)); FHost := Copy(FHost,1,i-1); end; if Length(FContent)=0 then FContent := '/'; FCs.OnDisconnect := MyDisconnect; FCs.OnRead := MyOnRead; FCs.OnWrite := MyOnWrite; FCs.Host := FHost; FCs.Port := Port; FCs.ClientType := ctNonBlocking; FCs.active := true; while not FReady do begin Application.Processmessages; Sleep(50); end; finally end; end; { procedure TForm3.Button3Click(Sender: TObject); Procedure AddSep; begin Memo1.Lines.Add('_______________________________________________'); end; begin Memo1.Text := Memo1.Text + TOldClientSocketTest.GetPage('www.devworx.com'); AddSep; Memo1.Text := Memo1.Text + TOldClientSocketTest.GetPage('http://www.jmarshall.com/easy/http/'); AddSep; Memo1.Text := Memo1.Text + TOldClientSocketTest.GetPage('http://www.delphipraxis.net'); AddSep; end; } end. |
AW: ClientSocket
Mit dieser Methode kannst du blocking auf ankommende Daten warten. Allerdings solltest du dir ein Protokoll überlegen, um Pakete korrekt zu trennen und um zu wissen, wann ein Paket vollständig angekommen ist:
Delphi-Quellcode:
In diesem Falle sende ich jedem Paket 2 Byte mit der Länge vorweg. Der Empfangsbuffer ist auch nur für Pakete von maximal 2^16 Bytes ausgelegt. Solltest du dir aber relativ leicht anpassen können.
procedure TBasicBackendConnector.ReceivePacket(var Command: Word;
Data: Pointer; var Size: Word); var Stream: TWinSocketStream; Buffer: array[0..1024 * 64 - 1] of Byte; PacketLength: Word; begin Stream := TWinSocketStream.Create(FSocket.Socket, 10000); try if (Stream.WaitForData(10000)) then begin PacketLength := FSocket.Socket.ReceiveLength; if (PacketLength > 0) then begin if (FPacketSize = 0) then begin FSocket.Socket.ReceiveBuf(FPacketSize, 2); end; if (FPacketSize > 0) then begin if ((PacketLength - 2) >= FPacketSize) then begin FSocket.Socket.ReceiveBuf(Buffer[0], FPacketSize); Size := FPacketSize; // INFO: Vollständiges Paket ist jetzt im Buffer enthalten FPacketSize := 0; end else begin ReceivePacket(Command, Data, Size); end; end; end else begin FSocket.Close; end; end; finally Stream.Free; end; end; Wenn du magst, schau gerne auch mal in die Demoanwendung für mein kürzlich entwickeltes Netzwerkprotokoll rein: ![]() Dort werden auch die blocking Sockets benutzt. Und eventuell bekommst du dort auch ein paar Anregungen, was das Protokoll angeht. |
AW: ClientSocket
Oder vllt. kannst du ja auch irgendwie das HTTP-Protokoll verwenden? Hast du Einfluß auf den Server? Denn HTTP ist ja darauf ausgelegt eine Request abzuschicken und dann auf eine Response zu warten. Dafür könnte man dann z.B. TIdHTTP von den Indys nehmen.
|
AW: ClientSocket
Vielen vielen Dank für eure Antworten, damit habt ihr mir sehr geholfen.
Schönes Wochenende und LG, Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz