Socketverbindung



  • ich habe ein Messgerät, das ich über eine Socketverbindung anspreche. Die Verbindung funktioniert bereits. Nun wollte ich die Messwertabrfrage in eine Threadklasse packen. Leider funktioniert das nicht. Kann den Fehler auch nicht finden. Hier mal die Klasse:

    __fastcall Awi::Awi(bool CreateSuspended)
    	: TThread(CreateSuspended),
         status(false),
         ch4GehaltFerm(0),
         co2GehaltFerm(0),
         o2GehaltFerm(0),
         h2GehaltFerm(0),
         h2sGehaltFerm(0),
         socket(new TClientSocket(NULL))
    {
    	Priority = tpNormal;
    
       memset(send,0,32);
       memset(rec,0,128);
       socket->Host = "192.168.0.37";
       socket->Port = 2080;
    }
    //---------------------------------------------------------------------------
    __fastcall Awi::~Awi()
    {
       socket->Close();
    	delete socket;
    }
    //---------------------------------------------------------------------------
    void __fastcall Awi::Execute()
    {
    	while(!Terminated)
       {
          ErfasseWerte();
          Sleep(1000);
       }
    }
    //---------------------------------------------------------------------------
    void Awi::ErfasseWerte()
    {
    	socket->Active = true;
       status = socket->Socket->Connected;
    	socket->Socket->SendBuf(send,32);
       Sleep(100);
       socket->Socket->ReceiveBuf(rec,128);
    
       ch4GehaltFerm = ((rec[22]<<8) + rec[23])/10.00;
       co2GehaltFerm = ((rec[16]<<8) + rec[17])/10.0;
       o2GehaltFerm  = ((rec[20]<<8) + rec[21])/100.0;
       h2GehaltFerm  = ((rec[40]<<8) + rec[41]);
       h2sGehaltFerm = ((rec[18]<<8) + rec[19]);
       socket->Active = true;
    }
    //---------------------------------------------------------------------------
    double Awi::GetCH4GehaltFerm() {return ch4GehaltFerm;}
    double Awi::GetCO2GehaltFerm() {return co2GehaltFerm;}
    double Awi::GetO2GehaltFerm()  {return o2GehaltFerm;}
    double Awi::GetH2GehaltFerm()  {return h2GehaltFerm;}
    double Awi::GetH2SGehaltFerm() {return h2sGehaltFerm;}
    //---------------------------------------------------------------------------
    bool Awi::GetStatus() {return status;}
    

    wenn ich den Thread dann starte über awi->Resume() und mir den Status anzeigen lasse, kommt keine Vebindung zustande.
    Wo könnte der Fehler liegen. Habe bisher immer nur die Komponete TClientSocket verwendet, und damit funktioniert die Verbindung.



  • rudpower schrieb:

    Wo könnte der Fehler liegen.

    In deinem Programm.

    Du gehst mit der Netzwerkverbindung um, als ob du jemanden anrufst und dabei einfach in den Hörer redest, ohne darauf zu achten ob sich über jemand gemeldet hat ...

    Denke erstmal darüber nach, was du tun willst ...



  • möglicher Fehler: wird der Thread überhaupt gestartet (du startest mit Resume; vorher ein Suspend zu oft aufgerufen?)

    was passiert, wenn der Thread so aussähe?

    void __fastcall Awi::Execute()
    {
        while(!Terminated)
       {
          if(socket->Active == false)
            {
              socket->Host = "192.168.0.37";
              socket->Port = 2080;
              socket->Open();
            }
          Sleep(1000); 
          ErfasseWerte();
       }
    }
    //---------------------------------------------------------------------------
    void Awi::ErfasseWerte()
    {
    
       status = socket->active;
    ...
    


  • habs mal so probiert, aber keine Änderung. Es gibt auch keinen Fehler. Ich vermute den Fehler beim Erzeugen des Objekts socket(new TClientSocket(NULL)). Ist das so richtig? Der Parameter darf doch bestimmt nicht Null sein?

    Das Objekt der Threadklasse Awi erzeug ich in meiner Form1 so:

    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
    	TTimer *Timer1;
    	TStaticText *StaticText1;
    	void __fastcall Timer1Timer(TObject *Sender);
    
    private:	// Anwender-Deklarationen
    	Awi* awi; //Deklaration hier
    };
    

    Definition in Konstruktorliste der Form:

    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner), awi(new Awi(false))
    {
        awi->Resume();
    }
    

    In einem Timer hol ich mir die Werte über:

    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    	StaticText1->Caption = FloatToStr(awi->GetCH4GehaltFerm());
    }
    

    ich denke mal da liegt der Fehler. Denn wenn ich die Komponete ClientSocket nehme funktioniert es. Was meint ihr?



  • hab grad keinen BCB zum testen zur Hand, aber müsste das nicht socket = new TClientSocket heissen?



  • ja habs in der Konstruktorliste gemacht da ist die Syntax so. Nur bei dem Parameter bin ich mir unsicher ob NULL richtig ist.

    Edit: Ich habe gerade nochmal eine neue Form erstellt und die TSocketKomponente zur Laufzeit erzeugen lassen. Das hat funktioniert und der Messwert wird auch angezeigt. Über den Thread funktioniert es leider immer noch nicht. Jmd eine Idee?

    So hat es funktioniert:

    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner), socket(new TClientSocket(NULL))
    {
       socket->Host = "192.168.0.37";
       socket->Port = 2080;
    }
    //---------------------------------------------------------------------------
    __fastcall TForm1::~TForm1()
    {
    	socket->Close();
       delete socket;
    }
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
       socket->Open();
       socket->Socket->SendBuf(send, 32);
       Sleep(10);
       socket->Socket->ReceiveBuf(rec, 128);
       Edit1->Text = ((rec[22]<<8) + rec[23])/10.0; //Anzeige des Werts auf der Form
    }
    


  • hat noch jmd eine Idee? Hab schon alles probiert, kann den Fehler einfach nicht finden. Habe mal probiert in den Thread in die Funktion ErfasseWerte einen random Wert in die Variable zu schreiben. Ruf ich diesen Wert dann in meiner Form über die Get-Methode ab funktioniert es. Über die Socketverbindung klappts leider nicht.



  • Versuch mal

    {
       socket->Host = "192.168.0.37";
       socket->Port = 2080;
       socket->ClientType = ctBlocking;
    }
    


  • hab das mit dem ctBlocking grad mal in meinem Testprogramm ausprobiert und es funktionierte. Mach ich das in meinem Hauptprogramm werden die Messwerte kurz angezeigt und dann wird das Programm beendet. Woran könnte das liegen? Ich erhalte folgende Fehlermeldung :
    Im Projekt Project1.exe ist eine Exception der Klasse ESocketError aufgetreten. Meldung:
    "Windows-Socket-Fehler: Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen(10053), auf API 'recv" Prozess wurde angehalten.

    lasse ich das ctBlocking weg oder nehme ctNonBlocking gibts keinen Fehler aber auch keinen Messwert.

    (Was man noch wissen muss ist, dass mein Messgerät nach jedem ReceiveBuf die Verbindung verliert. Ich muss also immer wieder neu verbinden.)

    Mein Code sieht jetzt so aus:

    __fastcall Awi::Awi(bool CreateSuspended)
    	: TThread(CreateSuspended),
         ch4GehaltFerm(0),
         socket(new TClientSocket(NULL))
    {
       socket->Host = "192.168.0.37";
       socket->Port = 2080;
       socket->ClientType = ctBlocking;
    }
    //---------------------------------------------------------------------------
    __fastcall Awi::~Awi()
    {
       socket->Close();
    	delete socket;
    }
    //---------------------------------------------------------------------------
    void __fastcall Awi::Execute()
    {
    	while(!Terminated)
       {
          memset(send,0,32);
          memset(rec,0,128);
    
          socket->Open();
          socket->Socket->SendBuf(send, 32);
          Sleep(100);
          socket->Socket->ReceiveBuf(rec, 128);
          ErfasseWerte();
          Sleep(1000);
       }
    }
    //---------------------------------------------------------------------------
    void Awi::ErfasseWerte()
    {
       ch4GehaltFerm = ((rec[22]<<8) + rec[23])/10.0;
    }
    

Anmelden zum Antworten