TCP-Server/Client



  • Hallo ihr VCL'er,

    ich habe ein mehr oder weniger großes Problem mit den Komponenten TcpClient und TcpServer. Und zwar will ich so etwas bauen, was alle gesendete Daten einer Anwendung mitloggt und diese Daten unverändert weiter sendet.
    Leider funktioniert das nicht ganz so gut, da ich mich wahrscheinlich noch nicht so gut mit den beiden Komponenten auskenne. Hier Folgender Codeansatz:

    Bei den Event "TcpServer1Accept"

    void __fastcall TForm1::TcpServer1Accept(TObject *Sender, TCustomIpClient *ClientSocket)
    
    {
      Memo5->Lines->Add("TcpServer Accept: "+String(ClientSocket->RemoteHost)+":"+String(ClientSocket->RemotePort));
      char puffer[1024]="";
      int puffersize = 1024;
      int recivedBytes = -1;
      do{
    	recivedBytes = ClientSocket->ReceiveBuf( puffer, puffersize);
    	Memo1->Lines->Add(AnsiString(puffer));
    	Memo1->Lines->Add("*****");
    	Memo1->Lines->Add(AnsiString(recivedBytes));
    	Memo1->Lines->Add("*****");
    	//TcpClient1->SendBuf(puffer,recivedBytes);
    	TcpClient1->Sendln(String(puffer));
      }while(recivedBytes>1024);
    }
    

    Auszug aus der Memo1 wenn ich per FireFox ansteuere:

    GET / HTTP/1.1
    Host: localhost:80
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; de; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
    Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 115
    Connection: keep-alive

    *****
    389
    *****

    Bei den Event "TcpClient1Send":

    void __fastcall TForm1::TcpClient1Send(TObject *Sender, PChar Buf, int &DataLen)
    {
      Memo5->Lines->Add("TcpClient Send");
      Memo4->Lines->Add(AnsiString(Buf));
      Memo4->Lines->Add("*****");
      Memo4->Lines->Add(AnsiString(DataLen));
      Memo4->Lines->Add("*****");
    }
    

    Auszug aus der Memo4 wenn ich per FireFox ansteuere:

    ??????????›??????????????????????????????????????????????????‹???????????›????????????????????????????????????????›??????????????????????????›??????????????›?????????????????????›????????????????

    *****
    391
    *****

    Bei den Event "TcpClient1Receive":

    void __fastcall TForm1::TcpClient1Receive(TObject *Sender, PChar Buf, int &DataLen)
    
    {
      Memo5->Lines->Add("TcpClient Receive");
      Memo4->Lines->Add(AnsiString(Buf));
      Memo4->Lines->Add("*****");
      Memo4->Lines->Add(AnsiString(DataLen));
      Memo4->Lines->Add("*****");
    }
    

    Memo4 bleibt ist leer.

    Auszug der Memo5 über den gesamten Ablauf:

    TcpClient CreateHandle
    TcpClient Error: 10035
    TcpServer CreateHandle
    TcpServer GetThread
    TcpServer Accept: 127.0.0.1:2537
    TcpClient Send

    Hoffe jemand kann mir helfen.

    Mit freundlichen Grüßen

    Eles



  • Habe es hin bekommen das es jetzt Funktioniert.
    Nun habe ich noch ein anderes Problem.
    Und zwar bekomme ich bei den TForm1::TcpServer1Accept Event ja die Daten zu gesendet, wenn später weitere Daten gesendet werden, werden diese nicht aufgelistet. Wie schaffe ich es auch die weiteren Daten auszuwerten?
    <-Gelöst

    Und wie schicke ich an den Client Daten Zurück? Per

    TcpServer2->Sendln("test1");
    	ClientSocket->Sendln("test2");
    

    in TcpServer1Accept Event wird bei den Client das TcpClient1Receive Event nicht ausgelöst.



  • Hallo Eles,

    kannst Du mir mal bitte mitteilen, wie Du es gelöst hast?
    Hänge nämlich gerade am gleichen Problem und bin nach dem Wochenende
    jetzt etwas ratlos. Wird bestimmt auch andere interessieren...

    Dein Eintrag:
    Habe es hin bekommen das es jetzt Funktioniert.
    Nun habe ich noch ein anderes Problem.
    Und zwar bekomme ich bei den TForm1::TcpServer1Accept Event ja die Daten zu gesendet, wenn später weitere Daten gesendet werden, werden diese nicht aufgelistet. Wie schaffe ich es auch die weiteren Daten auszuwerten?<-Gelöst

    Danke schon Mal im Voraus.

    Gruß Stefan



  • Mich wundert, dass Eles das mit TCP/Ip Sockets hinbekommen hat, eigentlich benutzt man für sowas einen Packetsniffer wie pcap.
    Aber bevor ich spekuliere: Was genau willst du erreichen?



  • Hallo DocShoe,

    ich empfange Daten von anderen PCs und Telefonanlagen mittels
    IP. Dazu verwende ich die Komponente TTcpServer unter Borland 2007.

    Mit

    void __fastcall TForm1::frm1_TcpServerAccept(TObject *Sender, TCustomIpClient *ClientSocket)
    

    und

    iAnz  =ClientSocket->ReceiveBuf(puffer,iAnzP);
    

    empfange ich die Daten; erhalte aber damit beim Beenden des Programms
    im IDE eine Fehlermeldung:
    *---------------------------
    Benachrichtigung über Debugger-Exception
    ---------------------------
    Im Projekt GAS_Portsniffer.exe ist eine Exception der Klasse EInvalidOperation mit der Meldung 'Element '' hat kein übergeordnetes Fenster' aufgetreten.
    ---------------------------
    Anhalten Fortsetzen Hilfe
    ---------------------------
    *

    Der Fehler tritt erst auf, wenn mind. einmal Daten gekommen sind. Daher
    hatte ich mal nachgehakt, welche Lösung er gefunden hat.

    Mir ist generell noch nicht klar, warum ich Daten in der Routine
    frm1_TcpServerAccept erhalte und nicht z.B. wie beim TTcpClient mit

    void __fastcall TForm1::frm1_TcpClientReceive(TObject *Sender, PChar Buf, int &DataLen)
    

    😕

    Gruß Stefan



  • Das ist doch eine ganz andere Anforderung als die, die Eles hatte. Die Fehlermeldung deutet daraufhin, dass der Fehler seinen Ursprung irgendwo in der GUI hat.
    Tritt der Fehler jedes Mal auf oder nur sporadisch?



  • Hallo DocShoe,

    habe mit dem Empfang noch Probleme, das der Connect vom Client beendet wird,
    wenn ich in der Routine TcpServerAccept() nur den Befehl

    iAnz  =ClientSocket->ReceiveBuf(puffer,iAnzP);				// Empfangene Daten auslesen
    

    einmal ausführe.

    Frage ich es aber in einer Schleife ab, dann bleibt die Verbindung dauerhaft bestehen:

    char puffer[1000];
     iAnzP=1000;
    
     iAnz =-1; 
     while(iAnz!=0) {							                    // solange auslesen, bis kein Zeichen mehr empfangen wird
      if(frm1_TcpServer->Active==false || oTcpOK==false) { break; }  // connect prüfen und ggf. Abbruch der Schleife
      Application->ProcessMessages();						        // events abarbeiten
    
      iAnz  =ClientSocket->ReceiveBuf(puffer,iAnzP);				 // Empfangene Daten auslesen
      zTxt  =AnsiString(puffer);							         // und in String aus Puffer auslesen
      //zTxt=ClientSocket->Receiveln("\0");                          // geht nur jedes 2.Mal ????
    
      TextRTF(100,clBlue,8,"Arial",-1,RTFE,"\tRecieve\t"+zTxt);      // und im RTF ablegen
     }
    

    Und sporadisch bekomme ich so auch Bruchstücke des Vorgängerdatensatzes mit rein (immer wenn schnell hintereinander Daten kommen). Irgendwie verstehe ich
    nicht, warum unter Accept Daten eingelesen werden und nicht wie bei TcpClient
    mittels Recieve Befehl... 😕

    Die Fehlermeldung tritt nur auf, wenn mind. 1x Daten gekommen sind. Leider
    sind diese Meldungen ja nicht sehr aussagekräftig und Debugmodus komme ich
    nicht weiter, weil der Fehler erst auftritt, wenn der eigentliche Quellcode
    abgearbeitet ist bzw. keiner mehr vorhanden ist.

    Gruß Stefan


Anmelden zum Antworten