TCP Socket



  • wie initialisiere ich das Array am besten mit 0-Bytes? Ist das mit memset ok? Normal kenn ich ja char send[32]={0};
    Ich hab aber send in der Klasse im Header deklariert. Wie initialisier ich nun das Array im Konstruktor? send[32]={0}; geht jeden Falls nicht. Mit einer for-Schleife geht ja auch aber vll geht ja auch einfacher.



  • Hallo

    Da dürfte memset das kürzeste sein, und auch schneller als eine Schleife. Da char ja ein POD ist, brauchst du dir um nichtaufgerufene Konstruktoren von char keine Sorgen machen.

    bis bald
    akari



  • blöd gefragt: was ist ein POD?



  • Hallo

    Plain Old Datatype : Ein Datentyp der genauso wie in C behandelt wird : also z.B. int, bool, float, C-Arrays, aber auch struct, wenn es keine Methoden und nur Datenelemente besitzt, die selber PODs sind. Vorteil : Diese Datentypen brauchen keine Konstruktoren und können z.B. mit memset auf 0 gesetzt werden, auch in Form eines Arrays. Bei einem std::vectorstd::string dürfte man das nicht machen.

    bis bald
    akari



  • ah ok alles klar. Ich hab immer elementare Datentypen dazu gesagt.

    Hab ein paar Probleme mit dem Auslesen der Messwerte. Mit dem Debugger kann ich die Daten bereits mit der Ausdrucksüberwachung sehen. Nun will ich sie noch ausgeben können als AnsiString zB in ein Editfeld oder Memo. Ich zeig einfach mal meine Klasse:

    class c_Awi{
       private:
          unsigned char send[32];
          unsigned char rec[128];
          TClientSocket* socket;
       public:
    	c_Awi(AnsiString IP, int Port);
    	~c_Awi();
    	char* ReceiveData(int Adresse); 
    };
    c_Awi::c_Awi(AnsiString IP, int Port):socket(new TClientSocket(NULL)) {
       memset(send,0,32);
       memset(rec,0,128);
       socket->Host = IP;
       socket->Port = Port;
    	socket->Active = true;
    }
    //---------------------------------------------------------------------------
    c_Awi::~c_Awi() {delete socket;}
    //---------------------------------------------------------------------------
    //in dieser Methode wollt ich eigentlich das Feld angeben, das dann ausgegeben werden soll. Ich denke das muss ich anders machen: 
    char* c_Awi::ReceiveData(int Adresse) {
    	socket->Socket->SendBuf(send,32);
       socket->Socket->ReceiveBuf(rec,128);
       return &rec[Adresse]; 
    }
    

    und hier meine Formklasse:

    class TForm1 : public TForm {
    __published:
    	TMemo *Memo;
    private:	
    	c_Awi* o_Awi; //hier meine Deklaration 
    public:	
    	__fastcall TForm1(TComponent* Owner);
    	__fastcall ~TForm1();
    };
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner), o_Awi(new c_Awi("192.168.0.37",2080)) {} //hier erzeug ich mein Objekt in der Konstruktorliste
    //---------------------------------------------------------------------------
    __fastcall TForm1::~TForm1() {delete o_Awi;}
    

    Da ja ein Messwert immer aus 2 Byte (also 2 Feldelementen besteht) muss ich diese dann noch irgendwie kombinieren. Aber erst mal wollt ich die einzelnen Felder auslesen können



  • * Du kannst mal BinToHex() anschauen um die Dtaen roh auszugeben.
    * Du kannst zwei Bytes die zusammen einen Wert bilden beispielsweise so zusammensetzen:

    int value = (rec[14] << 8) + rec[15];
    

    Allerdings musst du die Endianness klären, also welches Byte höherwertig ist.



  • ist mein code oben soweit erst mal ok?

    Laut Handbuch gilt das Big Endian Format. Das höherwertige Bit steht an niederen Adresse. In Feld 50 steht zB 0x80 und in Feld 51 steht 0x08. Wie komm ich nun an den Messwert 21.8? (Der steht auf der Anzeige des Geräts, daher kenn ich den)



  • habe erfahren das ich so auf den Wert komme:
    8*256+80 also (rec[50]*256 + rec[51])/100 oder ((rec[50]<<8)+rec[51])/100
    warum 256? Wie sieht das Beispiel bitweise aus, also was passiert hier in Binärschreibweise? Hab leider keine Erfahrungen mit dem BigEndianFormat.



  • Kann jetzt auf die Werte zugreifen. Habe noch das Problem, dass wenn ich die Methode ReceiveBuf aufrufe sich die Socket-Verbindung danach wieder trennt. Somit kann ich die Werte nicht aktualisieren. Hab eine Variable erstellt um die Active-Eigenschaft des Sockets zu prüfen. Immer wenn ich Messdaten empfange ist die Verbindung wieder getrennt. Ist das normal? Ich öffne die Verbindung im Konstruktor der Klasse wo ich mein TClientSocket Objekt erzeuge mit: meinSocketObjekt->Active=true; Dann sollte die Verbindung eigentlich offen bleiben bis ich das Objekt wieder delete. Das mach ich erst im Destruktor.



  • kan es vielleicht sein, dass das Gerät die Verbindung nach SendBuf oder SendReceive automatisch trennt? Gibt es vielleicht eine Alternative zu SendBuf/SendReceive?



  • Hallo

    Wenn das Gerät wirklich selber die Verbindung trennt, dann liegt es nicht am TSocket. Dann must du nach jeder Trennung eben die Verbindung neu öffen (Active = true) oder eine neue Socket-Instanz erstellen.

    bis bald
    akari


Anmelden zum Antworten