Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: VCL (C++ Builder) ::  Protokollanleitung als fertiges Paket schreiben     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 23:11:43 20.01.2012   Titel:   Protokollanleitung als fertiges Paket schreiben            Zitieren

Hallo Leute!
ich bin schon seit Jahren aus der Praxis draussen und möchte mich mal wieder an ein Projekt ranwagen. Ich habe eine Dokumentation wie ein Paket aufgebaut sein muss, aber leider noch keine Idee wie man anhand dieser Anleitung das Paket in Quelltext fasst. Ich hoffe, das ihr mir weiterhelfen könnt. Die Anleitung sieht wie folgt aus:

Packet format:
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
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
27
28
29
30
31
32
33
34
35
36
37
int32

32-bit        unsigned integer
1 byte        bits 7..0 of value
1 byte        bits 15..8 of value
1 byte        bits 23..16 of value
1 byte        bits 31..24 of value



Word

int32       Size        Number of bytes in word, excluding trailing null byte.
char[]      Content     Word contents -- must not contain any null bytes.
char        Terminator  Trailing null byte.



Packet

int32       Sequence    Bit 31: 0 = The command in this
                        command/response pair originated on the
                        server 1 = The command in this
                        command/response pair originated on the client.



                        Bit 30: 0 = Request, 1 = Response
                        Bits 29..0: Sequence number
                        (this is used to match requests/responses
                         in a full duplex transmission).

int32       Size        Total size of packet, in bytes.
int32       NumWords    Number of words following the packet header.
Word[N]     Words       N words

A packet cannot be more than 16384 bytes in size.
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
int32

32-bit unsigned integer
1 byte bits 7..0 of value
1 byte bits 15..8 of value
1 byte bits 23..16 of value
1 byte bits 31..24 of value



Word

int32 Size Number of bytes in word, excluding trailing null byte.
char[] Content Word contents -- must not contain any null bytes.
char Terminator Trailing null byte.



Packet

int32 Sequence Bit 31: 0 = The command in this
command/response pair originated on the
server 1 = The command in this
command/response pair originated on the client.



Bit 30: 0 = Request, 1 = Response
Bits 29..0: Sequence number
(this is used to match requests/responses
in a full duplex transmission).

int32 Size Total size of packet, in bytes.
int32 NumWords Number of words following the packet header.
Word[N] Words N words

A packet cannot be more than 16384 bytes in size.
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
int32

32-bit        unsigned integer
1 byte        bits 7..0 of value
1 byte        bits 15..8 of value
1 byte        bits 23..16 of value
1 byte        bits 31..24 of value



Word

int32       Size        Number of bytes in word, excluding trailing null byte.
char[]      Content     Word contents -- must not contain any null bytes.
char        Terminator  Trailing null byte.



Packet

int32       Sequence    Bit 31: 0 = The command in this
                        command/response pair originated on the
                        server 1 = The command in this
                        command/response pair originated on the client.



                        Bit 30: 0 = Request, 1 = Response
                        Bits 29..0: Sequence number
                        (this is used to match requests/responses
                         in a full duplex transmission).

int32       Size        Total size of packet, in bytes.
int32       NumWords    Number of words following the packet header.
Word[N]     Words       N words

A packet cannot be more than 16384 bytes in size.


Kann mir bitte jemand helfen das ganze in Quelltext zu fassen damit ich mal den Buzug zueinander verstehe. Ich weiß momentan gar nicht wie ich anfangen soll
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 02:17:39 21.01.2012   Titel:              Zitieren

Sooo, ich habe nun endlich ne Idee gehabt und habe angefangen:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Word
{

  unsigned int Size;
  char Content[128];
  char Terminator;

};


struct Paket
{

  unsigned int Sequence;
  unsigned int Size;
  unsigned int NumWords;
  Word words[];

};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Word
{

unsigned int Size;
char Content[128];
char Terminator;

};


struct Paket
{

unsigned int Sequence;
unsigned int Size;
unsigned int NumWords;
Word words[];

};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Word
{

  unsigned int Size;
  char Content[128];
  char Terminator;

};


struct Paket
{

  unsigned int Sequence;
  unsigned int Size;
  unsigned int NumWords;
  Word words[];

};


Und nun die Anwendung dessen:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  Word Inhalt;
  Paket Datenpaket;


  strcpy(Inhalt.Content,"login.plainText Passwort");
  Inhalt.Terminator = 0;
  Inhalt.Size = 128;

  Datenpaket.Sequence = 22222222222222222222222222222201;
  Datenpaket.Size = sizeof(Datenpaket);
  Datenpaket.NumWords = 2;


  ClientSocket1->Socket->SendBuf((char*)&Datenpaket,sizeof(Datenpaket));
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Word Inhalt;
Paket Datenpaket;


strcpy(Inhalt.Content,"login.plainText Passwort");
Inhalt.Terminator = 0;
Inhalt.Size = 128;

Datenpaket.Sequence = 22222222222222222222222222222201;
Datenpaket.Size = sizeof(Datenpaket);
Datenpaket.NumWords = 2;


ClientSocket1->Socket->SendBuf((char*)&Datenpaket,sizeof(Datenpaket));
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  Word Inhalt;
  Paket Datenpaket;


  strcpy(Inhalt.Content,"login.plainText Passwort");
  Inhalt.Terminator = 0;
  Inhalt.Size = 128;

  Datenpaket.Sequence = 22222222222222222222222222222201;
  Datenpaket.Size = sizeof(Datenpaket);
  Datenpaket.NumWords = 2;


  ClientSocket1->Socket->SendBuf((char*)&Datenpaket,sizeof(Datenpaket));


Aber leider funktioniert es nicht und ich weiß momentan nicht woran es liegt.
Hier ist die originale PDF Datei der Protokollbeschreibung:
http://hotfile.com/dl/142949213/b431df4/BF3_PC_Server_Remote_Administration_Protocol.pdf.html
_Stephan_
Mitglied

Benutzerprofil
Anmeldungsdatum: 07.04.2009
Beiträge: 112
Beitrag _Stephan_ Mitglied 08:19:12 23.01.2012   Titel:              Zitieren

Ich hab mir jetzt das PDF _nicht_ angeschaut, jedoch vermute ich, daß die Daten per Ethernet verschickt werden sollen.
Hierbei ist darauf zu achten, daß die Struktur gepackt wird.
D.h. das die Daten alle hintereinander im Speicher liegen und dann auch so verschickt werden.
Deine struct Word wird vermutlich als 3x32 Bit Wert im Speicher abgelegt sein, was durch das Packen verhindert wird.

Im Builder geht das Packen so:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma pack(push,1) //packen beginnen
struct Word
{
  unsigned int Size;
  char Content[128];
  char Terminator;
};
struct Paket
{
  unsigned int Sequence;
  unsigned int Size;
  unsigned int NumWords;
  Word words[];
};
#pragma
pack(pop) //packen beenden
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma pack(push,1) //packen beginnen
struct Word
{
unsigned int Size;
char Content[128];
char Terminator;
};
struct Paket
{
unsigned int Sequence;
unsigned int Size;
unsigned int NumWords;
Word words[];
};
#pragma
pack(pop) //packen beenden
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma pack(push,1) //packen beginnen
struct Word
{
  unsigned int Size;
  char Content[128];
  char Terminator;
};
struct Paket
{
  unsigned int Sequence;
  unsigned int Size;
  unsigned int NumWords;
  Word words[];
};
#pragma
pack(pop) //packen beenden


Ein weiterer Tipp, was bezüglich Ethernet, meiner Meinung nach, sehr wichtig ist, schau dir das Programm Wireshark an. Dies ist ein Ethernet Sniffer, womit Du sehen kannst, was deine Anwendung wirklich verschickt.

Viel Erfolg.
MfG Stephan
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 11:13:27 23.01.2012   Titel:              Zitieren

Das kann so auch nicht funktionieren, weil deine char Arrays immer eine fixe Länge von 128 haben. Im Protokoll ist definiert, dass jedes Word ein Attribut Content hat, das von genau einem abschließenden Nullbyte terminiert wird. Eigentlich brauchst du keine eigene Datenstrukturen für dein Paket, denn im Grunde sind die Daten nur Zeichenketten, die in einem bestimmten Format abgesendet werden. Um ein Paket zusammenzubauen kannst du Klassen der STL benutzen:

C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <string>
#include
<iostream>
#include
<sstream>
#include
<iterator>
#include
<vector>

std::string make_packet( unsigned int Sequence, const std::vector<std::string>& words )
{
    // 1. Schritt: Paketlänge bestimmen
    unsigned int TotalSize = 4;    // 4 Byte für Paketheader
    for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
    {
        TotalSize    += 4;                // 4 Byte für Länge des Wortes
        TotalSize    += it->size(); // Anzahl der Zeichen des Wortes
        TotalSize    += 1;                // 1 Byte für abschließende 0
    }
    TotalSize += 4;    // 4 Byte für Anzahl der Wörter
    TotalSize += 4;    // 4 Byte für Gesamtgröße des Pakets

    std::ostringstream oss;

    // Sequence ID (oder was auch immer) schreiben
    oss << static_cast<char>( Sequence & 0xff )
         << static_cast<char>( (Sequence >> 8) & 0xff )
         << static_cast<char>( (Sequence >> 16) & 0xff )
         << static_cast<char>( (Sequence >> 24) & 0xff );

    // Gesamtgröße schreiben
    oss << static_cast<char>( TotalSize & 0xff )
         << static_cast<char>( (TotalSize >> 8) & 0xff )
         << static_cast<char>( (TotalSize >> 16) & 0xff )
         << static_cast<char>( (TotalSize >> 24) & 0xff );

    // Anzahl der Wörter schreiben
    oss << static_cast<char>( words.size() & 0xff )
         << static_cast<char>( (words.size() >> 8) & 0xff )
         << static_cast<char>( (words.size() >> 16) & 0xff )
         << static_cast<char>( (words.size() >> 24) & 0xff );

    // Wörter selbst schreiben
    for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
    {
        // Anzahl der Zeichen im Wort schreiben
        oss << static_cast<char>( it->size() & 0xff )
             << static_cast<char>( (it->size() >> 8) & 0xff )
             << static_cast<char>( (it->size() >> 16) & 0xff )
             << static_cast<char>( (it->size() >> 24) & 0xff );

        // Wort schreiben
        oss << *it;

        // abschließendes 0-Byte schreiben
        oss << static_cast<char>( 0 );
    }
    return oss.str();
}

int main()
{
    std::vector<std::string> Words;
    Words.push_back( "Hello" );
    Words.push_back( "World" );

    std::string Packet = make_packet( 1, Words );
}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <string>
#include
<iostream>
#include
<sstream>
#include
<iterator>
#include
<vector>

std::string make_packet( unsigned int Sequence, const std::vector<std::string>& words )
{
// 1. Schritt: Paketlänge bestimmen
unsigned int TotalSize = 4; // 4 Byte für Paketheader
for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
{
TotalSize += 4; // 4 Byte für Länge des Wortes
TotalSize += it->size(); // Anzahl der Zeichen des Wortes
TotalSize += 1; // 1 Byte für abschließende 0
}
TotalSize += 4; // 4 Byte für Anzahl der Wörter
TotalSize += 4; // 4 Byte für Gesamtgröße des Pakets

std::ostringstream oss;

// Sequence ID (oder was auch immer) schreiben
oss << static_cast<char>( Sequence & 0xff )
<< static_cast<char>( (Sequence >> 8) & 0xff )
<< static_cast<char>( (Sequence >> 16) & 0xff )
<< static_cast<char>( (Sequence >> 24) & 0xff );

// Gesamtgröße schreiben
oss << static_cast<char>( TotalSize & 0xff )
<< static_cast<char>( (TotalSize >> 8) & 0xff )
<< static_cast<char>( (TotalSize >> 16) & 0xff )
<< static_cast<char>( (TotalSize >> 24) & 0xff );

// Anzahl der Wörter schreiben
oss << static_cast<char>( words.size() & 0xff )
<< static_cast<char>( (words.size() >> 8) & 0xff )
<< static_cast<char>( (words.size() >> 16) & 0xff )
<< static_cast<char>( (words.size() >> 24) & 0xff );

// Wörter selbst schreiben
for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
{
// Anzahl der Zeichen im Wort schreiben
oss << static_cast<char>( it->size() & 0xff )
<< static_cast<char>( (it->size() >> 8) & 0xff )
<< static_cast<char>( (it->size() >> 16) & 0xff )
<< static_cast<char>( (it->size() >> 24) & 0xff );

// Wort schreiben
oss << *it;

// abschließendes 0-Byte schreiben
oss << static_cast<char>( 0 );
}
return oss.str();
}

int main()
{
std::vector<std::string> Words;
Words.push_back( "Hello" );
Words.push_back( "World" );

std::string Packet = make_packet( 1, Words );
}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <string>
#include
<iostream>
#include
<sstream>
#include
<iterator>
#include
<vector>

std::string make_packet( unsigned int Sequence, const std::vector<std::string>& words )
{
    // 1. Schritt: Paketlänge bestimmen
    unsigned int TotalSize = 4;    // 4 Byte für Paketheader
    for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
    {
        TotalSize    += 4;                // 4 Byte für Länge des Wortes
        TotalSize    += it->size(); // Anzahl der Zeichen des Wortes
        TotalSize    += 1;                // 1 Byte für abschließende 0
    }
    TotalSize += 4;    // 4 Byte für Anzahl der Wörter
    TotalSize += 4;    // 4 Byte für Gesamtgröße des Pakets

    std::ostringstream oss;

    // Sequence ID (oder was auch immer) schreiben
    oss << static_cast<char>( Sequence & 0xff )
         << static_cast<char>( (Sequence >> 8) & 0xff )
         << static_cast<char>( (Sequence >> 16) & 0xff )
         << static_cast<char>( (Sequence >> 24) & 0xff );

    // Gesamtgröße schreiben
    oss << static_cast<char>( TotalSize & 0xff )
         << static_cast<char>( (TotalSize >> 8) & 0xff )
         << static_cast<char>( (TotalSize >> 16) & 0xff )
         << static_cast<char>( (TotalSize >> 24) & 0xff );

    // Anzahl der Wörter schreiben
    oss << static_cast<char>( words.size() & 0xff )
         << static_cast<char>( (words.size() >> 8) & 0xff )
         << static_cast<char>( (words.size() >> 16) & 0xff )
         << static_cast<char>( (words.size() >> 24) & 0xff );

    // Wörter selbst schreiben
    for( std::vector<std::string>::const_iterator it = words.begin(); it != words.end(); ++it )
    {
        // Anzahl der Zeichen im Wort schreiben
        oss << static_cast<char>( it->size() & 0xff )
             << static_cast<char>( (it->size() >> 8) & 0xff )
             << static_cast<char>( (it->size() >> 16) & 0xff )
             << static_cast<char>( (it->size() >> 24) & 0xff );

        // Wort schreiben
        oss << *it;

        // abschließendes 0-Byte schreiben
        oss << static_cast<char>( 0 );
    }
    return oss.str();
}

int main()
{
    std::vector<std::string> Words;
    Words.push_back( "Hello" );
    Words.push_back( "World" );

    std::string Packet = make_packet( 1, Words );
}


Du kannst dein Packet natürlich auch als Klasse modellieren und den Stream operator überladen:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Packet
{
   unsigned int Sequence;
   std::vector<std::string> Words;

   Packet() : Sequence( 0 )
   {
   }

   Packet( unsigned int Sequence ) : Sequence( Sequence )
   {
   }
};

ostream& operator<<( ostream& os, const Packet& op )
{
   // Code siehe make_packet
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Packet
{
unsigned int Sequence;
std::vector<std::string> Words;

Packet() : Sequence( 0 )
{
}

Packet( unsigned int Sequence ) : Sequence( Sequence )
{
}
};

ostream& operator<<( ostream& os, const Packet& op )
{
// Code siehe make_packet
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Packet
{
   unsigned int Sequence;
   std::vector<std::string> Words;

   Packet() : Sequence( 0 )
   {
   }

   Packet( unsigned int Sequence ) : Sequence( Sequence )
   {
   }
};

ostream& operator<<( ostream& os, const Packet& op )
{
   // Code siehe make_packet
}

}

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 13:30:24 23.01.2012   Titel:              Zitieren

Vielen Dank euch beiden!

@DocShoe:
Hast du schonmal mit dem Rcon Protokoll gearbeitet?


Der Server gibt immer noch keine Antwort aus, aber er kickt mich wenn ich mehrere Packete hintereinander sende:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
unsigned char *buff;
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());


ClientSocket1->Socket->SendBuf(buff, sizeof buff);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
unsigned char *buff;
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());


ClientSocket1->Socket->SendBuf(buff, sizeof buff);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
unsigned char *buff;
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());


ClientSocket1->Socket->SendBuf(buff, sizeof buff);


Kann es sein das die Standard TCP Client Komponente von der BCB
Auswahl nicht mit gängigen Standards zurecht kommt und nur der BCB TCP Client mit dem BCB TCP Server kommunizieren kann?


Zuletzt bearbeitet von Zero01 am 13:38:23 23.01.2012, insgesamt 3-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 14:23:12 23.01.2012   Titel:              Zitieren

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 0, Words );

ClientSocket1 -> Host=  "210.198.162.241";
ClientSocket1 -> Port=  27505;
ClientSocket1 -> Open();

ClientSocket1->Socket->SendBuf((char*)&Packet,sizeof(Packet) );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 0, Words );

ClientSocket1 -> Host= "210.198.162.241";
ClientSocket1 -> Port= 27505;
ClientSocket1 -> Open();

ClientSocket1->Socket->SendBuf((char*)&Packet,sizeof(Packet) );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
std::vector<std::string> Words;
Words.push_back( "login.plainText password");


std::string Packet = make_packet( 0, Words );

ClientSocket1 -> Host=  "210.198.162.241";
ClientSocket1 -> Port=  27505;
ClientSocket1 -> Open();

ClientSocket1->Socket->SendBuf((char*)&Packet,sizeof(Packet) );


Die Logindaten entsprechen nicht der Realität in diesem Beispiel. So wie es aussieht kommt das Paket richtig beim Server an, da ich nun direkt ein disconnect bekomme wenn ich dieses erneut sende. Aber wie bewege ich das ClientSocket dazu Daten entgegenzunehmen?
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 14:30:34 23.01.2012   Titel:              Zitieren

Zero01 schrieb:
Vielen Dank euch beiden!

@DocShoe:
Hast du schonmal mit dem Rcon Protokoll gearbeitet?

C/C++ Code:
std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());
ClientSocket1->Socket->SendBuf(buff, sizeof buff);
C/C++ Code:
std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());
ClientSocket1->Socket->SendBuf(buff, sizeof buff);
C/C++ Code:
std::string Packet = make_packet( 3, Words );
strcpy(buff ,Packet.c_str());
ClientSocket1->Socket->SendBuf(buff, sizeof buff);



Nein, habe ich nicht.
Du kannst strcpy hier nicht verwenden, da es sich bei dem Puffer nicht um Klartext sondern um Binärdaten handelt. Dabei ist es sehr wahrscheinlich, dass der Puffer mehrere Nullbytes enthält und strcpy ab dem ersten nicht mehr weiterkopiert. Ersetz´ den zitierten Code mal durch

C/C++ Code:
std::string Packet = make_packet( 3, Words );
if( !Packet.empty() )
{
   ClientSocket1->Socket->SendBuf( &Packet[0], Packet.size() );
}
C/C++ Code:
std::string Packet = make_packet( 3, Words );
if( !Packet.empty() )
{
ClientSocket1->Socket->SendBuf( &Packet[0], Packet.size() );
}
C/C++ Code:
std::string Packet = make_packet( 3, Words );
if( !Packet.empty() )
{
   ClientSocket1->Socket->SendBuf( &Packet[0], Packet.size() );
}

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 14:40:14 23.01.2012   Titel:              Zitieren

Super!!! ich weiß gar nicht wie ich dir danken soll. Der Server kommuniziert nun endlich mit meinem Client. Jetzt muss ich nur noch deine Funktion wie das Paket formatiert wird richtig verstehen um das Paket vom Server wiederum zu entschlüsseln
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 18:37:59 23.01.2012   Titel:              Zitieren

Ich hab folgende Funktion erstellt:
C/C++ Code:
void read_packet( unsigned char *readbuff, unsigned int length);
C/C++ Code:
void read_packet( unsigned char *readbuff, unsigned int length);
C/C++ Code:
void read_packet( unsigned char *readbuff, unsigned int length);



ClientSocket1 gibt bei Datenempfang das Paket an die Funktion weiter:
C/C++ Code:
int length = Socket->ReceiveLength();
unsigned char *buffer = (unsigned char*) malloc (length);

Socket->ReceiveBuf(buffer,sizeof(buffer));

read_packet(buffer, length);
C/C++ Code:
int length = Socket->ReceiveLength();
unsigned char *buffer = (unsigned char*) malloc (length);

Socket->ReceiveBuf(buffer,sizeof(buffer));

read_packet(buffer, length);
C/C++ Code:
int length = Socket->ReceiveLength();
unsigned char *buffer = (unsigned char*) malloc (length);

Socket->ReceiveBuf(buffer,sizeof(buffer));

read_packet(buffer, length);



Die Funktion selbst:
C/C++ Code:
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
27
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
27
void read_packet(unsigned char *readbuff, unsigned int length)
{


    unsigned int headersize = 4;

           



    // Sequence ID lesen und in Form1->Memo1 ausgeben



    // Gesamtgröße lesen



    // Anzahl der Wörter lesen



    // Wörter lesen und in Form1->Memo1 ausgeben


       (so wie ich das sehe ab dem 12. byte das Pakets)

}
C/C++ Code:
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
27
void read_packet(unsigned char *readbuff, unsigned int length)
{


unsigned int headersize = 4;





// Sequence ID lesen und in Form1->Memo1 ausgeben



// Gesamtgröße lesen



// Anzahl der Wörter lesen



// Wörter lesen und in Form1->Memo1 ausgeben


(so wie ich das sehe ab dem 12. byte das Pakets)

}
C/C++ Code:
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
27
void read_packet(unsigned char *readbuff, unsigned int length)
{


    unsigned int headersize = 4;

           



    // Sequence ID lesen und in Form1->Memo1 ausgeben



    // Gesamtgröße lesen



    // Anzahl der Wörter lesen



    // Wörter lesen und in Form1->Memo1 ausgeben


       (so wie ich das sehe ab dem 12. byte das Pakets)

}


Wenn ich das Datenfelde direkt ab dem 12. Byte aus dem Paket auslese und im Memo ausgebe bekomme ich nur Zahlensalat. Normalerweise sollte doch ab dem 12. Byte die Wörter kommen :confused: Die for Schleife habe ich wieder gelöscht weil dies ein vollkommen falscher Lösungsansatz war. Bin ich auf der richtigen Spur oder ist der Ansatz falsch?

Das gesendete Paket und das zu empfangende Paket sind absolut identisch vom Aufbau her


Zuletzt bearbeitet von Zero01 am 19:14:41 23.01.2012, insgesamt 3-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 10:19:34 24.01.2012   Titel:              Zitieren

So funktioniert TCP/IP nicht. Du kannst nicht davon ausgehen, dass dein komplettes Telegramm mit einem ReceiveBuf Aufruf empfangen werden kann. Außerdem hast du noch einen anderen dicken Bock in deinem Code:

C/C++ Code:
Socket->ReceiveBuf(buffer,sizeof(buffer));
C/C++ Code:
Socket->ReceiveBuf(buffer,sizeof(buffer));
C/C++ Code:
Socket->ReceiveBuf(buffer,sizeof(buffer));


sizeof(buffer) liefert 4, da buffer ein Zeiger ist und Zeiger nun mal nur 4 Byte im Speicher belegen (zumindest bei Windows 32bit). Du liest also nur 4 Byte, kein Wunder, dass ab Position 12 nix Vernünftiges steht. Auch das Verwenden von malloc/free ist in C++ völlig überflüssig (zumal ich deinem Code nirgendwo ein free sehe). Deine receive Funktion könnte z.B. so aussehen:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<unsigned char> MyClass::receive()
{
   // vector mit entsprechender Empfangsgröße anlegen
   std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength, 0 );

   if( !ReceiveBuffer.empty() )
   {
      // Daten in Puffer lesen
      unsigned int RecvCount = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );

      // vector auf Größe tatsächlich empfangener Bytes bringen
      ReceiveBuffer.resize( RecvCount );
   }
   return ReceiveBuffer;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<unsigned char> MyClass::receive()
{
// vector mit entsprechender Empfangsgröße anlegen
std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength, 0 );

if( !ReceiveBuffer.empty() )
{
// Daten in Puffer lesen
unsigned int RecvCount = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );

// vector auf Größe tatsächlich empfangener Bytes bringen
ReceiveBuffer.resize( RecvCount );
}
return ReceiveBuffer;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::vector<unsigned char> MyClass::receive()
{
   // vector mit entsprechender Empfangsgröße anlegen
   std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength, 0 );

   if( !ReceiveBuffer.empty() )
   {
      // Daten in Puffer lesen
      unsigned int RecvCount = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );

      // vector auf Größe tatsächlich empfangener Bytes bringen
      ReceiveBuffer.resize( RecvCount );
   }
   return ReceiveBuffer;
}


Als nächstes musst du die eingehenden Daten an einen Empfangspuffer anhängen. Jedes Mal, wenn du Daten empfängst musst du Folgende Schritte machen:

1) empfangene Daten an Empfangspuffer anhängen
2) prüfen, ob mind. 8 Byte im Empfangspuffer stehen (da ab Byte 4 die Gesamttelegrammlänge steht)
3) wenn weniger als 8 Byte empfangen worden sind => 9)
4) Gesamttelegrammlänge bestimmen
5) prüfen, ob entsprechend viele Daten im Empfangspuffer stehen. Wenn nein => 9)
6) Telegrammdaten bestimmen und behandeln
7) behandelte Telegrammdaten vom Anfang des Empfangspuffers löschen
8) => 2)
9) auf weitere Daten warten

Dir fehlen offensichtlich noch Grundlagen, insbesondere bei der Verwendung der STL. Fast sämtliche dynamische Speicheranforderungen lassen sich durch Klassen der STL effizienter und robuster realisieren als mit malloc/free. Vielleicht solltest du dir ein modernes C++ Buch besorgen und erst ein Mal etwas lesen.

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 18:57:31 24.01.2012   Titel:              Zitieren

Stimmt,jetzt fällt es mir wieder ein. Wenn ich malloc benutze macht es nur Sinn wenn die Funktion jediglich den Pointer auf den allokierten Speicher zurück gibt, abgearbeitet wird und dann anschliessend mit free() freigegeben wird. free() innerhalb der Funktion geht nicht, da nach dem return kein weiterer code abgehandelt wird und davor eine Speicherzugriffsverletzung entstehen würde, weil ein Pointer auf eine Speicheradresse aufgerufen wird die nicht mehr existiert.

Mit Vektoren in diesem Umfang bin ich jetzt zum ersten mal durch dich in Kontakt gekommen und werde mich da fix einlesen. Durch deine Erläuterungen leuchtet mir ein, dass dies ein wirklich gutes Werkzeug zur dynamischen Speicherbelegung ist. Entschuldigt bitte die ein oder andere sehr naive Frage. Hab jetzt seit 6 Jahren zum ersten mal wieder den CBuilder 6 vor Augen und in dieser Zeit scheint sehr vieles auf der Strecke geblieben zu sein. Ich bemühe mich wieder reinzukommen. Vielen Dank für die super Erklärungen und die Starthilfe!!!!


Noch eine Frage
C/C++ Code:
&ReceiveBuffer[0]
C/C++ Code:
&ReceiveBuffer[0]
C/C++ Code:
&ReceiveBuffer[0]


0 ist der Index ab dem gelesen werden soll und Receive.Length gibt an bis wohin gelesen werden soll in dem Funktionsaufruf Socket->ReceiveBuf()?


TCP arbeitet ja mit Fehlerkorrektur und deshalb kann es vorkommen das ein nicht richtig übertragenes Paket erneut gesendet wird. Wenn ein Datensatz das TCP Frame in seiner Größe überschreitet, kapselt TCP die Daten in mehrere Pakete. Daher kann ich nicht von ausgehen das alles in einem Paket übertragen wird.
Richtig so?


Zuletzt bearbeitet von Zero01 am 19:06:58 24.01.2012, insgesamt 3-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 21:28:47 24.01.2012   Titel:              Zitieren

Ich hab nun mal um ne Ausgabe zu bekommen folgendes gemacht (sauber in die Klasse integrieren und Funktionen erstellen mache ich später):

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 String daten = "";
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );



      if(recbytes > 12)   //ab dem 12. byte die wörter
     {
          ReceiveBuffer.resize(recbytes);


          for(int i = 12; i <= recbytes; i++)
         {

           daten += ReceiveBuffer[i] ;


         }

       ReceiveBuffer.clear();
       Memo1->Lines->Add(daten); //Empfangene Daten sequenziell in Memo schreiben

     }
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
String daten = "";
std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );



if(recbytes > 12) //ab dem 12. byte die wörter
{
ReceiveBuffer.resize(recbytes);


for(int i = 12; i <= recbytes; i++)
{

daten += ReceiveBuffer[i] ;


}

ReceiveBuffer.clear();
Memo1->Lines->Add(daten); //Empfangene Daten sequenziell in Memo schreiben

}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 String daten = "";
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );



      if(recbytes > 12)   //ab dem 12. byte die wörter
     {
          ReceiveBuffer.resize(recbytes);


          for(int i = 12; i <= recbytes; i++)
         {

           daten += ReceiveBuffer[i] ;


         }

       ReceiveBuffer.clear();
       Memo1->Lines->Add(daten); //Empfangene Daten sequenziell in Memo schreiben

     }


In Memo1 wird als Serverantwort folgendes ausgegeben:
1400085110107110111119110671111091099711010000




Um dies zu decodieren habe ich eine Phyton Funktion gefunden:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def DecodeInt32(data):
   return unpack('<I', data[0 : 4])[0]


    def DecodeWords(size, data):
    numWords = DecodeInt32(data[0:])
    words = []
    offset = 0
    while offset < size:
        wordLen = DecodeInt32(data[offset : offset + 4])
        word = data[offset + 4 : offset + 4 + wordLen]
        words.append(word)
        offset += wordLen + 5
                return words
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def DecodeInt32(data):
return unpack('<I', data[0 : 4])[0]


def DecodeWords(size, data):
numWords = DecodeInt32(data[0:])
words = []
offset = 0
while offset < size:
wordLen = DecodeInt32(data[offset : offset + 4])
word = data[offset + 4 : offset + 4 + wordLen]
words.append(word)
offset += wordLen + 5
return words
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def DecodeInt32(data):
   return unpack('<I', data[0 : 4])[0]


    def DecodeWords(size, data):
    numWords = DecodeInt32(data[0:])
    words = []
    offset = 0
    while offset < size:
        wordLen = DecodeInt32(data[offset : offset + 4])
        word = data[offset + 4 : offset + 4 + wordLen]
        words.append(word)
        offset += wordLen + 5
                return words


Könnte mir bitte jemand helfen den Python Code in C++ zu übersetzen?


Zuletzt bearbeitet von Zero01 am 21:30:07 24.01.2012, insgesamt 1-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 11:21:06 25.01.2012   Titel:              Zitieren

Nochmal: Dir fehlen Grundlagen. Der Code, den du hier vorgestellt hast, zeigt deutlich, dass du die Problematik nicht vollständig erfasst hast und auch nicht in der Lage bist, eine Lösung umzusetzen. Sich Codeschnipsel aus dem Internet zusammenzusuchen und sich irgendwas zusammenzuschrauben führt in der Regel nicht zum gewünschten Ergebnis. Aber mach dir nix draus, wir haben alle mal angefangen, so ganz auf dem Holzweg bist du nicht ;)
Vielleicht solltest du den Computer einfach mal für ´ne Stunde ausmachen und dir in Ruhe überlegen, was du erreichen willst und wie du das erreichen kannst. Geh im Kopf (und einem Blatt Papier) mal durch, welche Fälle auftreten können und wie man das in den Griff bekommt.
Was passiert denn, wenn bei deinem letzten Code jedes Byte einzeln ankommt?

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 17:01:55 25.01.2012   Titel:              Zitieren

Tataaa, die grauen Zellen arbeiten wieder @ DocShoe :p

C/C++ Code:
Header
std::vector<unsigned char> Framesammler;
unsigned int isPaketsizereached;
C/C++ Code:
Header
std::vector<unsigned char> Framesammler;
unsigned int isPaketsizereached;
C/C++ Code:
Header
std::vector<unsigned char> Framesammler;
unsigned int isPaketsizereached;


C/C++ Code:
Main
Framesammler.clear();
isPaketsizereached = 0;
C/C++ Code:
Main
Framesammler.clear();
isPaketsizereached = 0;
C/C++ Code:
Main
Framesammler.clear();
isPaketsizereached = 0;



C/C++ Code:
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
27
28
29
30
31
32
33
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
27
28
29
30
31
32
33
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

     if(Framesammler.size() >= 4)
     isPaketsizereached  =  Framesammler[4];


      if(Framesammler.size() > 12 && isPaketsizereached == Framesammler.size())
     {
          String daten = "";
          for(unsigned int i = 12; i <= Framesammler.size(); i++)
         {

           daten +=  Framesammler[i] ;

         }

         Memo1->Lines->Add(daten) ;

         //Da vollständig übertragen Sammelpuffer und Paketgröße zurücksetzen für nächste Pakete
         Framesammler.clear();
         isPaketsizereached = 0;

     }

     ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
ReceiveBuffer.resize(recbytes);


//Frames sammeln und anhängen bis Paket vollständig übertragen ist.
Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

//Hilfsvariable um Übertragungsende zu bestimmen.
//Paketgröße aus dem Paketheader holen.

if(Framesammler.size() >= 4)
isPaketsizereached = Framesammler[4];


if(Framesammler.size() > 12 && isPaketsizereached == Framesammler.size())
{
String daten = "";
for(unsigned int i = 12; i <= Framesammler.size(); i++)
{

daten += Framesammler[i] ;

}

Memo1->Lines->Add(daten) ;

//Da vollständig übertragen Sammelpuffer und Paketgröße zurücksetzen für nächste Pakete
Framesammler.clear();
isPaketsizereached = 0;

}

ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

     if(Framesammler.size() >= 4)
     isPaketsizereached  =  Framesammler[4];


      if(Framesammler.size() > 12 && isPaketsizereached == Framesammler.size())
     {
          String daten = "";
          for(unsigned int i = 12; i <= Framesammler.size(); i++)
         {

           daten +=  Framesammler[i] ;

         }

         Memo1->Lines->Add(daten) ;

         //Da vollständig übertragen Sammelpuffer und Paketgröße zurücksetzen für nächste Pakete
         Framesammler.clear();
         isPaketsizereached = 0;

     }

     ReceiveBuffer.clear();


Meun DocShoe!
Mein Ziel ist nicht das abkupfern des Phytonquelltextes sondern das Wiso Weshalb Warum. Das mit dem Computerausschalten, sich mal Hinsetzen und deine Hinweiße zu befolgen hat hoffentlich anhand des hier gezeigten Ergebnisses verdeutlicht, dass es bei mir noch nicht Hoffnungslos ist :confused: Der Befehl "serverinfo" sendet mehrere Pakete hintereinander und diese hängen jetzt schön aneinander im Hilfspuffer den ich dann Auslese ohne den ganzen Headerkram drin stehen zu haben.

Gestern kurz vorm einschlafen kam mir noch ein Gedanke die eigentlichen Paketdaten in 4Byte Schnipsel rauszukopieren und ein '0x' davor zu setzen um den Lösungsweg mal nach Hexadezimal zu versuchen um endlich aus dem Zahlenwirrwar Buchstaben zu erhalten. Da ich aber noch keinen genauen Anhaltspunkt habe überlege ich ob das zum Ziel führt. Was meinst du?


Zuletzt bearbeitet von Zero01 am 17:16:38 25.01.2012, insgesamt 3-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 17:32:13 25.01.2012   Titel:              Zitieren

C/C++ Code:
isPaketsizereached = 0;
C/C++ Code:
isPaketsizereached = 0;
C/C++ Code:
isPaketsizereached = 0;

Ist ausserdem überflüssig weil es bei entsprechender Größe eh überschrieben wird
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 18:56:52 25.01.2012   Titel:              Zitieren

Wow! Das ist ja fast gut ;) Ich würde die Hilfsvariable isPaketsizereached anders nennen, ein guter Name wäre z.B. TelegramLength.

Du hast immer noch mehrere Fehler drin:

- wenn z.B. 1.5 Telegramme in deinem Puffer stehen
darfst du nur soviele Daten entnehmen, wie das Telegramm lang ist
musst du soviele Daten aus dem Puffer entfernen, wie das Telegramm lang ist

- du greifst auf den festen Index 4 des Buffers zu, da steht allerdings nur das niederwertigste Byte der Telegrammlänge drin. Richtigerweise müsstest du die Bytes der Indizes 5-7 noch berücksichtigen (und entsprechend bitshiften).
Die erste Überprüfung gegen 4 ist falsch, denn in den ersten 4 Bytes steht nur die Sequence ID und nicht die Telegrammlänge. Danach musst du gegen TelegramLength und nicht gegen 12 prüfen. Ausserdem musst du noch den Fall betrachten, dass mehrere Telegramme im Puffer stehen können.

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool Done = true;
do
{
   // Annahme: kein vollständiges Telegramm im Puffer
   Done = true;
   if( FrameSammler.size() >= 4 )
   {
      unsigned int TelegramLength = ?;

      if( FrameSammler.size() >= TelegramLength )
      {
         // mach was mit´m Telegramm

         // entferne behandelte Daten vom Anfang des Puffers

         // ggf. stehen weitere Telegramme im Puffer, weiterer Durchlauf notwendig

         Done = false;
      }
   }
}
while( !Done );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool Done = true;
do
{
// Annahme: kein vollständiges Telegramm im Puffer
Done = true;
if( FrameSammler.size() >= 4 )
{
unsigned int TelegramLength = ?;

if( FrameSammler.size() >= TelegramLength )
{
// mach was mit´m Telegramm

// entferne behandelte Daten vom Anfang des Puffers

// ggf. stehen weitere Telegramme im Puffer, weiterer Durchlauf notwendig

Done = false;
}
}
}
while( !Done );
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
bool Done = true;
do
{
   // Annahme: kein vollständiges Telegramm im Puffer
   Done = true;
   if( FrameSammler.size() >= 4 )
   {
      unsigned int TelegramLength = ?;

      if( FrameSammler.size() >= TelegramLength )
      {
         // mach was mit´m Telegramm

         // entferne behandelte Daten vom Anfang des Puffers

         // ggf. stehen weitere Telegramme im Puffer, weiterer Durchlauf notwendig

         Done = false;
      }
   }
}
while( !Done );


Edit:
Was das die Ausgabe in´s Memo angeht: Hexadezimale Ausgabe halte ich nicht für sooo schlau, daraus erkennt man nicht viel. Klartext ist da wesentlich besser. Und wie der Zufall so will gibt´s für std::string nen schönen Konstruktor, der dir Abschnitte aus einem Vektor herausfilettiert:

C/C++ Code:
std::string Line( FrameSammler.begin() +x, FrameSammler.begin() +x +y );
Memo->Lines->Add( Line.c_str() );
C/C++ Code:
std::string Line( FrameSammler.begin() +x, FrameSammler.begin() +x +y );
Memo->Lines->Add( Line.c_str() );
C/C++ Code:
std::string Line( FrameSammler.begin() +x, FrameSammler.begin() +x +y );
Memo->Lines->Add( Line.c_str() );

_________________
1. Dies ist die erste Regel des Tautologieclubs.


Zuletzt bearbeitet von DocShoe am 19:01:51 25.01.2012, insgesamt 2-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 21:27:23 25.01.2012   Titel:              Zitieren

Ich hab jetzt folgendes:

C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{


     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

      if(Framesammler.size() >= 4)
      {
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
         TelegramLength  =  Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

      }

      if(Framesammler.size() >= TelegramLength)
     {

       /*
          //Reine Telegrammlänge abarbeiten
            for(int x = 12; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x, Framesammler.end());
             Memo1->Lines->Add(Line.c_str());
          }

          Noch Fehlerhaft!

       */



           bool done = false;
           bool deletebuffer = false;

          do
      {
          //Wenn im Puffer mehr als das abgearbeitete Telegram steht
          if(Framesammler.size() > TelegramLength)
         {

            std::vector<unsigned char> Tempbuffer;
            Tempbuffer.clear();

            Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin()+ TelegramLength,Framesammler.end());
            Framesammler.clear();
            Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());

            done = true;

         }
         else
         {
            deletebuffer = true;
         }

       }
       while(done = false);




         //Wenn vollständig übertragen Sammelpuffer zurücksetzen für nächste Pakete,ansonsten neu formaierten Puffer beibehalten
       if (deletebuffer == true)
         Framesammler.clear();



   }

     ReceiveBuffer.clear();


}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{


std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
ReceiveBuffer.resize(recbytes);


//Frames sammeln und anhängen bis Paket vollständig übertragen ist.
Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

//Hilfsvariable um Übertragungsende zu bestimmen.
//Paketgröße aus dem Paketheader holen.

if(Framesammler.size() >= 4)
{
//Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
TelegramLength = Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

}

if(Framesammler.size() >= TelegramLength)
{

/*
//Reine Telegrammlänge abarbeiten
for(int x = 12; x < TelegramLength; x++)
{
std::string Line(Framesammler.begin() + x, Framesammler.end());
Memo1->Lines->Add(Line.c_str());
}

Noch Fehlerhaft!

*/



bool done = false;
bool deletebuffer = false;

do
{
//Wenn im Puffer mehr als das abgearbeitete Telegram steht
if(Framesammler.size() > TelegramLength)
{

std::vector<unsigned char> Tempbuffer;
Tempbuffer.clear();

Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin()+ TelegramLength,Framesammler.end());
Framesammler.clear();
Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());

done = true;

}
else
{
deletebuffer = true;
}

}
while(done = false);




//Wenn vollständig übertragen Sammelpuffer zurücksetzen für nächste Pakete,ansonsten neu formaierten Puffer beibehalten
if (deletebuffer == true)
Framesammler.clear();



}

ReceiveBuffer.clear();


}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{


     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());

     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

      if(Framesammler.size() >= 4)
      {
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
         TelegramLength  =  Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

      }

      if(Framesammler.size() >= TelegramLength)
     {

       /*
          //Reine Telegrammlänge abarbeiten
            for(int x = 12; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x, Framesammler.end());
             Memo1->Lines->Add(Line.c_str());
          }

          Noch Fehlerhaft!

       */



           bool done = false;
           bool deletebuffer = false;

          do
      {
          //Wenn im Puffer mehr als das abgearbeitete Telegram steht
          if(Framesammler.size() > TelegramLength)
         {

            std::vector<unsigned char> Tempbuffer;
            Tempbuffer.clear();

            Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin()+ TelegramLength,Framesammler.end());
            Framesammler.clear();
            Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());

            done = true;

         }
         else
         {
            deletebuffer = true;
         }

       }
       while(done = false);




         //Wenn vollständig übertragen Sammelpuffer zurücksetzen für nächste Pakete,ansonsten neu formaierten Puffer beibehalten
       if (deletebuffer == true)
         Framesammler.clear();



   }

     ReceiveBuffer.clear();


}



C/C++ Code:
//Reine Telegrammlänge abarbeiten
            for(int x = 12; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x, Framesammler.end());
             Memo1->Lines->Add(Line.c_str());
          }
C/C++ Code:
//Reine Telegrammlänge abarbeiten
for(int x = 12; x < TelegramLength; x++)
{
std::string Line(Framesammler.begin() + x, Framesammler.end());
Memo1->Lines->Add(Line.c_str());
}
C/C++ Code:
//Reine Telegrammlänge abarbeiten
            for(int x = 12; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x, Framesammler.end());
             Memo1->Lines->Add(Line.c_str());
          }

Puhh, da versteh ich noch nicht so ganz wie ich an die ganzen Wörter ran komme. Wörter werden ausgegeben aber sehen noch wie folgt aus mit Leerspalten im Memo
und Sonderzeichen dazwischen:

Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
OK
K

3



Server FragThe.Net is korrekte Mama - Hardcore - 1P Start!
ragThe.Net is korrekte Mama - Hardcore - 1P Start!
agThe.Net is korrekte Mama - Hardcore - 1P Start!
gThe.Net is korrekte Mama - Hardcore - 1P Start!
The.Net is korrekte Mama - Hardcore - 1P Start!
he.Net is korrekte Mama - Hardcore - 1P Start!
e.Net is korrekte Mama - Hardcore - 1P Start!
.Net is korrekte Mama - Hardcore - 1P Start!
Net is korrekte Mama - Hardcore - 1P Start!
et is korrekte Mama - Hardcore - 1P Start!
t is korrekte Mama - Hardcore - 1P Start!
 is korrekte Mama - Hardcore - 1P Start!
is korrekte Mama - Hardcore - 1P Start!
s korrekte Mama - Hardcore - 1P Start!
 korrekte Mama - Hardcore - 1P Start!
korrekte Mama - Hardcore - 1P Start!
orrekte Mama - Hardcore - 1P Start!
rrekte Mama - Hardcore - 1P Start!
rekte Mama - Hardcore - 1P Start!
ekte Mama - Hardcore - 1P Start!
kte Mama - Hardcore - 1P Start!
te Mama - Hardcore - 1P Start!
e Mama - Hardcore - 1P Start!
 Mama - Hardcore - 1P Start!
Mama - Hardcore - 1P Start!
ama - Hardcore - 1P Start!
ma - Hardcore - 1P Start!
a - Hardcore - 1P Start!
 - Hardcore - 1P Start!
- Hardcore - 1P Start!
 Hardcore - 1P Start!
Hardcore - 1P Start!
ardcore - 1P Start!
rdcore - 1P Start!
dcore - 1P Start!
core - 1P Start!
ore - 1P Start!
re - 1P Start!
e - 1P Start!
 - 1P Start!
- 1P Start!
 1P Start!
1P Start!
P Start!
 Start!
Start!
tart!
art!
rt!
t!
!





0





32
2





ConquestSmall0
onquestSmall0
nquestSmall0
questSmall0
uestSmall0
estSmall0
stSmall0
tSmall0
Small0
mall0
all0
ll0
l0
0

   



MP_Subway
P_Subway
_Subway
Subway
ubway
bway
way
ay
y





0





1





2





489
89
9





489
89
9





0










true
rue
ue
e





true
rue
ue
e





false
alse
lse
se
e





26100
6100
100
00
0





20104
0104
104
04
4




















EU
U





ams
ms
s





DE
E
Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
OK
K

3



Server FragThe.Net is korrekte Mama - Hardcore - 1P Start!
ragThe.Net is korrekte Mama - Hardcore - 1P Start!
agThe.Net is korrekte Mama - Hardcore - 1P Start!
gThe.Net is korrekte Mama - Hardcore - 1P Start!
The.Net is korrekte Mama - Hardcore - 1P Start!
he.Net is korrekte Mama - Hardcore - 1P Start!
e.Net is korrekte Mama - Hardcore - 1P Start!
.Net is korrekte Mama - Hardcore - 1P Start!
Net is korrekte Mama - Hardcore - 1P Start!
et is korrekte Mama - Hardcore - 1P Start!
t is korrekte Mama - Hardcore - 1P Start!
is korrekte Mama - Hardcore - 1P Start!
is korrekte Mama - Hardcore - 1P Start!
s korrekte Mama - Hardcore - 1P Start!
korrekte Mama - Hardcore - 1P Start!
korrekte Mama - Hardcore - 1P Start!
orrekte Mama - Hardcore - 1P Start!
rrekte Mama - Hardcore - 1P Start!
rekte Mama - Hardcore - 1P Start!
ekte Mama - Hardcore - 1P Start!
kte Mama - Hardcore - 1P Start!
te Mama - Hardcore - 1P Start!
e Mama - Hardcore - 1P Start!
Mama - Hardcore - 1P Start!
Mama - Hardcore - 1P Start!
ama - Hardcore - 1P Start!
ma - Hardcore - 1P Start!
a - Hardcore - 1P Start!
- Hardcore - 1P Start!
- Hardcore - 1P Start!
Hardcore - 1P Start!
Hardcore - 1P Start!
ardcore - 1P Start!
rdcore - 1P Start!
dcore - 1P Start!
core - 1P Start!
ore - 1P Start!
re - 1P Start!
e - 1P Start!
- 1P Start!
- 1P Start!
1P Start!
1P Start!
P Start!
Start!
Start!
tart!
art!
rt!
t!
!





0





32
2





ConquestSmall0
onquestSmall0
nquestSmall0
questSmall0
uestSmall0
estSmall0
stSmall0
tSmall0
Small0
mall0
all0
ll0
l0
0





MP_Subway
P_Subway
_Subway
Subway
ubway
bway
way
ay
y





0





1





2





489
89
9





489
89
9





0










true
rue
ue
e





true
rue
ue
e





false
alse
lse
se
e





26100
6100
100
00
0





20104
0104
104
04
4




















EU
U





ams
ms
s





DE
E
Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
OK
K

3



Server FragThe.Net is korrekte Mama - Hardcore - 1P Start!
ragThe.Net is korrekte Mama - Hardcore - 1P Start!
agThe.Net is korrekte Mama - Hardcore - 1P Start!
gThe.Net is korrekte Mama - Hardcore - 1P Start!
The.Net is korrekte Mama - Hardcore - 1P Start!
he.Net is korrekte Mama - Hardcore - 1P Start!
e.Net is korrekte Mama - Hardcore - 1P Start!
.Net is korrekte Mama - Hardcore - 1P Start!
Net is korrekte Mama - Hardcore - 1P Start!
et is korrekte Mama - Hardcore - 1P Start!
t is korrekte Mama - Hardcore - 1P Start!
 is korrekte Mama - Hardcore - 1P Start!
is korrekte Mama - Hardcore - 1P Start!
s korrekte Mama - Hardcore - 1P Start!
 korrekte Mama - Hardcore - 1P Start!
korrekte Mama - Hardcore - 1P Start!
orrekte Mama - Hardcore - 1P Start!
rrekte Mama - Hardcore - 1P Start!
rekte Mama - Hardcore - 1P Start!
ekte Mama - Hardcore - 1P Start!
kte Mama - Hardcore - 1P Start!
te Mama - Hardcore - 1P Start!
e Mama - Hardcore - 1P Start!
 Mama - Hardcore - 1P Start!
Mama - Hardcore - 1P Start!
ama - Hardcore - 1P Start!
ma - Hardcore - 1P Start!
a - Hardcore - 1P Start!
 - Hardcore - 1P Start!
- Hardcore - 1P Start!
 Hardcore - 1P Start!
Hardcore - 1P Start!
ardcore - 1P Start!
rdcore - 1P Start!
dcore - 1P Start!
core - 1P Start!
ore - 1P Start!
re - 1P Start!
e - 1P Start!
 - 1P Start!
- 1P Start!
 1P Start!
1P Start!
P Start!
 Start!
Start!
tart!
art!
rt!
t!
!





0





32
2





ConquestSmall0
onquestSmall0
nquestSmall0
questSmall0
uestSmall0
estSmall0
stSmall0
tSmall0
Small0
mall0
all0
ll0
l0
0

   



MP_Subway
P_Subway
_Subway
Subway
ubway
bway
way
ay
y





0





1





2





489
89
9





489
89
9





0










true
rue
ue
e





true
rue
ue
e





false
alse
lse
se
e





26100
6100
100
00
0





20104
0104
104
04
4




















EU
U





ams
ms
s





DE
E


:confused: :confused: :confused:
Es ist mir klar das durch die for Schleife mit stetig ansteigendem X nur Salat rauskommt, aber ich möchte nur diese Funktion des std::string verstehen um es debugen zu können
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 00:21:58 26.01.2012   Titel:              Zitieren

Nach etwas Probieren bekomme ich jetzt eine halbwegs stimmige Ausgabe:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
//Reine Telegrammlänge abarbeiten
            String temp = "";
            for(int x = 16; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
             temp = temp + Line.c_str();
          }

         
          Memo1->Lines->Add(temp);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
//Reine Telegrammlänge abarbeiten
String temp = "";
for(int x = 16; x < TelegramLength; x++)
{
std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
temp = temp + Line.c_str();
}


Memo1->Lines->Add(temp);
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
//Reine Telegrammlänge abarbeiten
            String temp = "";
            for(int x = 16; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
             temp = temp + Line.c_str();
          }

         
          Memo1->Lines->Add(temp);


Die Ausgabe sieht dann wie folgt aus:
http://up.picr.de/9354907myc.jpg


Die Frage ist jetzt wodurch dieser Zeichensalat zwischen den Wörtern entsteht und nicht korrekt ausgegeben wird.



Edit: Noch ein dicker Bock den ich geschossen hab:

C/C++ Code:
while(done == false);

//und nicht

while(done = false);
C/C++ Code:
while(done == false);

//und nicht

while(done = false);
C/C++ Code:
while(done == false);

//und nicht

while(done = false);


Jetzt hänge ich in ner Endlosschleife fest, wenn 1,5 Frames im Buffer stehen. Daher auch der Datensalat zwischen den Wörtern


Zuletzt bearbeitet von Zero01 am 00:30:41 26.01.2012, insgesamt 3-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 01:15:09 26.01.2012   Titel:              Zitieren

Die letzte überarbeitete Version für heute Nacht:
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());


     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

      if(Framesammler.size() >= 4)
      {
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
         TelegramLength  =  Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

      }

      if(Framesammler.size() >= TelegramLength)
     {


          //Reine Telegrammlänge abarbeiten
            String temp = "";
            for(unsigned int x = 16; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
             temp = temp + Line.c_str();
          }
          Memo1->Lines->Add(temp);




          bool done = false;
          do
      {
           //Wenn im Puffer mehr als das abgearbeitete Telegram steht
           //Wenn der Puffer das abgearbeitete Paket vollständig enthält

           if(Framesammler.size() >= TelegramLength)
          {

            std::vector<unsigned char> Tempbuffer;
            Tempbuffer.clear();

            //Vollständiges und zuvor abgearbeitetes Paket im Puffer ausschneiden und folgende Daten an den Anfang stellen
            Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin() + TelegramLength, Framesammler.end());
            Framesammler.clear();
            Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());


            TelegramLength = Framesammler.size();
            done = true;

          }
           else
          {
           TelegramLength = Framesammler.size();
           done = false;

          }

       }
        while(done == false);




   }

     ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
ReceiveBuffer.resize(recbytes);


//Frames sammeln und anhängen bis Paket vollständig übertragen ist.
Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());


//Hilfsvariable um Übertragungsende zu bestimmen.
//Paketgröße aus dem Paketheader holen.

if(Framesammler.size() >= 4)
{
//Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
TelegramLength = Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

}

if(Framesammler.size() >= TelegramLength)
{


//Reine Telegrammlänge abarbeiten
String temp = "";
for(unsigned int x = 16; x < TelegramLength; x++)
{
std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
temp = temp + Line.c_str();
}
Memo1->Lines->Add(temp);




bool done = false;
do
{
//Wenn im Puffer mehr als das abgearbeitete Telegram steht
//Wenn der Puffer das abgearbeitete Paket vollständig enthält

if(Framesammler.size() >= TelegramLength)
{

std::vector<unsigned char> Tempbuffer;
Tempbuffer.clear();

//Vollständiges und zuvor abgearbeitetes Paket im Puffer ausschneiden und folgende Daten an den Anfang stellen
Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin() + TelegramLength, Framesammler.end());
Framesammler.clear();
Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());


TelegramLength = Framesammler.size();
done = true;

}
else
{
TelegramLength = Framesammler.size();
done = false;

}

}
while(done == false);




}

ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());


     //Hilfsvariable um Übertragungsende zu bestimmen.
     //Paketgröße aus dem Paketheader holen.

      if(Framesammler.size() >= 4)
      {
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
         TelegramLength  =  Framesammler[4] >> Framesammler[5] >> Framesammler[6] >> Framesammler[7] ;

      }

      if(Framesammler.size() >= TelegramLength)
     {


          //Reine Telegrammlänge abarbeiten
            String temp = "";
            for(unsigned int x = 16; x < TelegramLength; x++)
          {
             std::string Line(Framesammler.begin() + x , Framesammler.begin() + x + 1);
             temp = temp + Line.c_str();
          }
          Memo1->Lines->Add(temp);




          bool done = false;
          do
      {
           //Wenn im Puffer mehr als das abgearbeitete Telegram steht
           //Wenn der Puffer das abgearbeitete Paket vollständig enthält

           if(Framesammler.size() >= TelegramLength)
          {

            std::vector<unsigned char> Tempbuffer;
            Tempbuffer.clear();

            //Vollständiges und zuvor abgearbeitetes Paket im Puffer ausschneiden und folgende Daten an den Anfang stellen
            Tempbuffer.insert(Tempbuffer.end(),Framesammler.begin() + TelegramLength, Framesammler.end());
            Framesammler.clear();
            Framesammler.insert(Framesammler.end(),Tempbuffer.begin(),Tempbuffer.end());


            TelegramLength = Framesammler.size();
            done = true;

          }
           else
          {
           TelegramLength = Framesammler.size();
           done = false;

          }

       }
        while(done == false);




   }

     ReceiveBuffer.clear();


Aber immernoch Headerdaten die sich im reinen Datenpuffer zwischenmogeln wenn mehrere Pakete gesendet werden. Eine Endlosschleife entsteht jetzt nicht mehr, aber die Daten werden noch genauso angezeigt wie in dem verlinkten Bild.


Zuletzt bearbeitet von Zero01 am 01:17:22 26.01.2012, insgesamt 1-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 10:27:05 26.01.2012   Titel:              Zitieren

Da ist wieder jede Menge Murks dabei...

- Zeile 12-17
Du prüfst gegen Länge 4, greifst aber auf Elemente 5-8 zu. Die Bestimmung der Telegrammlänge ist zudem noch falsch. Lies dir noch ein Mal das Kapitel zum Thema bit shifts durch.

- Zeile 23-30
WTF? Du baust für jedes einzelne Zeichen einen String und hängst den wieder an den Ausgabestring an. Das geht besser, weil du doch schon weißt, wie lang der String ist (steht so im Telegramm).

- Zeile 43-49
Hier kommt man auch ohne temp. Puffer aus. Du sollst nur die Daten des Telegramms vom Anfang des Puffers löschen, das geht mit einem erase Aufruf.

- Zeile 52 und Zeile 58
Die korrekte Telegrammlänge ist mit Sicherheit nicht die Anzahl der verbleibenden Bytes im Empfangspuffer.

also eigentlich fast alles... also nochmal von vorne. Immerhin stimmt das Empfangen und Speichern der Telegrammdaten.

1) Stehen genügend Daten bereit für den Telegrammkopf (Sequence ID + Telegrammlänge. Wieviel Bytes haben 2 int32?)? Wenn nein, dann weiter bei 7)
2) Telegrammlänge aus Bytes 5-8 bestimmen
3) Stehen genügend Daten für das Telegramm bereit? Wenn nein, dann weiter bei 7)
4) Behandle die ersten N Bytes des Puffers
5) Entferne die ersten N Bytes des Puffers
6) Zurück zu 1)
7) Zu wenig Daten für Telegramm vorhanden

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 13:41:25 26.01.2012   Titel:              Zitieren

Meun Doc!

Soweit habe ich jetzt all deine Korrekturen umgesetzt, allerdings Blick ich durchs Bitshifting noch nicht ganz durch. Ich veranlasse einen Linksshift, aber um wieviel Bit? 1 oder alle 8 pro byte?


Zudem habe ich die Funktion noch mal grundliegend umstrukturiert, ich denke so macht es jetzt eher Sinn:

C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());



     //Wenn der Puffer Paketdaten enthält dann prüfe und verarbeite
      if(Framesammler.size() > 0)
     {

          bool done = false;
          do
      {

             //Paketgröße aus dem Paketheader holen.
             //Sequence ID + Telegrammlänge. Wieviel Bytes haben 2 int32? = 8byte!

             if(Framesammler.size() >= 8)
            {
           
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
                            TelegramLength = 0;
                            TelegramLength += Framesammler[5] << 8;
                            TelegramLength += Framesammler[6] << 8;
                            TelegramLength += Framesammler[7] << 8;
                            TelegramLength += Framesammler[8] << 8;


                           // ShowMessage(TelegramLength);


            }
            else
            break
;


            if(Framesammler.size() >= TelegramLength)
           {
              //Reine Telegrammlänge abarbeiten
              std::string Line(Framesammler.begin() + 12 , Framesammler.begin() + TelegramLength);
              Memo1->Lines->Add(Line.c_str());


              //Vollständiges und zuvor abgearbeitetes Pakets im Puffer ausschneiden und folgende Daten an den Anfang stellen
              Framesammler.erase(Framesammler.begin(),Framesammler.begin() + TelegramLength);
              done = true;


                //Prüfen ob sich noch ein weiteres vollständiges Telegram im Puffer befindet
                //Wenn nicht, empfange weiter

                if (Framesammler.size() >= 8)
               {

                  //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
                  //Noch nicht angepasst, siehe oben.....

                  TelegramLength = 0;
                  TelegramLength = Framesammler[5] << Framesammler[6] << Framesammler[7] << Framesammler[8];


                  if (Framesammler.size() >= TelegramLength)
                  continue;

             
              }
              else
              break
;
           }
           else
           break
;
       }
        while(done == false);

   }

     ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
ReceiveBuffer.resize(recbytes);


//Frames sammeln und anhängen bis Paket vollständig übertragen ist.
Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());



//Wenn der Puffer Paketdaten enthält dann prüfe und verarbeite
if(Framesammler.size() > 0)
{

bool done = false;
do
{

//Paketgröße aus dem Paketheader holen.
//Sequence ID + Telegrammlänge. Wieviel Bytes haben 2 int32? = 8byte!

if(Framesammler.size() >= 8)
{

//Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
TelegramLength = 0;
TelegramLength += Framesammler[5] << 8;
TelegramLength += Framesammler[6] << 8;
TelegramLength += Framesammler[7] << 8;
TelegramLength += Framesammler[8] << 8;


// ShowMessage(TelegramLength);


}
else
break
;


if(Framesammler.size() >= TelegramLength)
{
//Reine Telegrammlänge abarbeiten
std::string Line(Framesammler.begin() + 12 , Framesammler.begin() + TelegramLength);
Memo1->Lines->Add(Line.c_str());


//Vollständiges und zuvor abgearbeitetes Pakets im Puffer ausschneiden und folgende Daten an den Anfang stellen
Framesammler.erase(Framesammler.begin(),Framesammler.begin() + TelegramLength);
done = true;


//Prüfen ob sich noch ein weiteres vollständiges Telegram im Puffer befindet
//Wenn nicht, empfange weiter

if (Framesammler.size() >= 8)
{

//Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
//Noch nicht angepasst, siehe oben.....

TelegramLength = 0;
TelegramLength = Framesammler[5] << Framesammler[6] << Framesammler[7] << Framesammler[8];


if (Framesammler.size() >= TelegramLength)
continue;


}
else
break
;
}
else
break
;
}
while(done == false);

}

ReceiveBuffer.clear();
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
     std::vector<unsigned char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
     int recbytes = Socket->ReceiveBuf( &ReceiveBuffer[0], ReceiveBuffer.size() );
     ReceiveBuffer.resize(recbytes);


     //Frames sammeln und anhängen bis Paket vollständig übertragen ist.
     Framesammler.insert(Framesammler.end(), ReceiveBuffer.begin(), ReceiveBuffer.end());



     //Wenn der Puffer Paketdaten enthält dann prüfe und verarbeite
      if(Framesammler.size() > 0)
     {

          bool done = false;
          do
      {

             //Paketgröße aus dem Paketheader holen.
             //Sequence ID + Telegrammlänge. Wieviel Bytes haben 2 int32? = 8byte!

             if(Framesammler.size() >= 8)
            {
           
                            //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
                            TelegramLength = 0;
                            TelegramLength += Framesammler[5] << 8;
                            TelegramLength += Framesammler[6] << 8;
                            TelegramLength += Framesammler[7] << 8;
                            TelegramLength += Framesammler[8] << 8;


                           // ShowMessage(TelegramLength);


            }
            else
            break
;


            if(Framesammler.size() >= TelegramLength)
           {
              //Reine Telegrammlänge abarbeiten
              std::string Line(Framesammler.begin() + 12 , Framesammler.begin() + TelegramLength);
              Memo1->Lines->Add(Line.c_str());


              //Vollständiges und zuvor abgearbeitetes Pakets im Puffer ausschneiden und folgende Daten an den Anfang stellen
              Framesammler.erase(Framesammler.begin(),Framesammler.begin() + TelegramLength);
              done = true;


                //Prüfen ob sich noch ein weiteres vollständiges Telegram im Puffer befindet
                //Wenn nicht, empfange weiter

                if (Framesammler.size() >= 8)
               {

                  //Bitshift der einzelnen bytes zur Ermittlung der Paketgröße
                  //Noch nicht angepasst, siehe oben.....

                  TelegramLength = 0;
                  TelegramLength = Framesammler[5] << Framesammler[6] << Framesammler[7] << Framesammler[8];


                  if (Framesammler.size() >= TelegramLength)
                  continue;

             
              }
              else
              break
;
           }
           else
           break
;
       }
        while(done == false);

   }

     ReceiveBuffer.clear();


Zuletzt bearbeitet von Zero01 am 13:48:25 26.01.2012, insgesamt 3-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 15:15:40 26.01.2012   Titel:              Zitieren

Zero01 schrieb:
Meun Doc!
Soweit habe ich jetzt all deine Korrekturen umgesetzt, allerdings Blick ich durchs Bitshifting noch nicht ganz durch.

Nein, hast du nicht.

Zero01 schrieb:

Ich veranlasse einen Linksshift, aber um wieviel Bit? 1 oder alle 8 pro byte?

Hängt vom Byte ab. Also ganz langsam: Ein int32 besteht aus 4 Byte. Jedes dieser Bytes hat eine bestimmte Wertigkeit (zum Vergleich: Dezimalsystem. Jede Stelle besteht aus einer Ziffer, aber abhängig von der Stelle hat diese Ziffer eine andere Wertigkeit. Ein Byte ist für die Bits 0-7, eins für 8-15, noch eins für 16-23 und schließlich eins für 24-31. In deiner Protokollbeschreibung ist beschrieben, welches Byte welche Wertigkeit hat.

Zero01 schrieb:

Zudem habe ich die Funktion noch mal grundliegend umstrukturiert, ich denke so macht es jetzt eher Sinn:


Ich glaube nicht :D. Du hast viel zu viele Überprüfungen für die Telegrammgröße drin, du kommst mit nur 2 aus (Tipp: Wenn 8 oder mehr Bytes im Puffer stehen, dann stehen auch mehr als 0 Bytes drin).
Die Bestimmung der Telegrammlänge stimmt immer noch nicht, aber das weißt du ja bereits.
Bei der Softwareentwicklung macht man sich übrigens vorher Gedanken zum Algorithmus und setzt diesen dann in Code um. Man probiert nicht solange, bis es irgendwann zufällig funktioniert. Du machst letzteres...

Langsam gehe ich auf dem Zahnfleisch... vielleicht erbarmt sich ja jemand anderes, das hier zu lösen, ich kann langsam nicht mehr :(

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 16:12:31 26.01.2012   Titel:              Zitieren

DocShoe schrieb:


Langsam gehe ich auf dem Zahnfleisch... vielleicht erbarmt sich ja jemand anderes, das hier zu lösen, ich kann langsam nicht mehr :(


Oh nicht wegen mir. Entschuldige bitte
Ich weiß das ich einiges noch nicht ganz durchblicke und evtl. auch dafür zu doof bin momentan strukturiert vor zu gehen. Ich versuchs trotzdem zu lösen.
Ich danke dir tausendfach für deine Hilfe


Zuletzt bearbeitet von Zero01 am 16:15:54 26.01.2012, insgesamt 1-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 17:18:42 26.01.2012   Titel:              Zitieren

C/C++ Code:
int32 size;
C/C++ Code:
int32 size;
C/C++ Code:
int32 size;


Hat im empfangenen Paket 4 byte Felder zu je 8 Bit. Das erste Byte ist das
niederwertigste, das vierte das höchstwertigste. Man könnte doch angefangen vom niederwertigsten Byte mit bitweise AND bis zum höchstwertigen Verknüpfen um die Ganzzahl int32 zu erhalten. Ist das so Richtig?
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 18:19:20 26.01.2012   Titel:              Zitieren

*Röchel* Na... gut... bevor ich wahnsinnig werde:

C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <string>
#include
<vector>
#include
<iostream>
#include
<iterator>

struct Packet
{
   unsigned int           Sequence;
   std::vector<std::string>   Words;

   Packet() : Sequence( 0 )
   {
   }        
};

void handle_packet( const Packet& Packet )
{
    std::cout << "Packet Sequence : " << std::hex << "0x" << Packet.Sequence << "\n";
    std::copy( Packet.Words.begin(), Packet.Words.end(), std::ostream_iterator<std::string>( std::cout, "\n" ) );
}

void handle_packets( std::vector<char>& Buffer )
{
    // Telegrammlänge steht in Bytes 5-8, daher müssen mindestens
    // 8 Byte im Puffer stehen

    while( Buffer.size() >= 8 )
    {
        // Telegrammlänge bestimmen.
        unsigned int TelegramLength = Buffer[4] | Buffer[5] << 8 | Buffer[6] << 16 | Buffer[7] << 24;

        // stehen genügend Daten im Puffer für das komplette Telegramm? Wenn nein, dann abbrechen
        if( Buffer.size() < TelegramLength ) return;

        Packet Packet;

        // Sequence steht in den ersten 4 Byte des Telegramms
        Packet.Sequence = Buffer[0] | Buffer[1] << 8 | Buffer[2] << 16 | Buffer[3] << 24;

        // Anzahl der Wörter steht in Bytes 9-12
        unsigned int WordCount = Buffer[8] | Buffer[9] << 8 | Buffer[10] << 16 | Buffer[11] << 24;

        // Zeiger auf Länge des 1. Wortes setzen
        char* WordPtr = &Buffer[12];

        // Wörter isolieren
        for( unsigned int i = 0; i < WordCount; ++i )
        {
            // Wortlänge steht in den ersten 4 Bytes
            unsigned int WordLength = WordPtr[0] | WordPtr[1] << 8 | WordPtr[2] << 16 | WordPtr[3] << 24;

            // Inhalt des Strings in Paket einfügen. Inhalt des Strings steht ab Byte 4
            // abschließendes Nullbyte ausnutzen, um aus char* einen std::string zu erzeugen

            Packet.Words.push_back( WordPtr +4 );

            // Wort überspringen (tatsächliche Wortlänge + 4 Byte für Präfix + 1 Byte abschließende 0)
            WordPtr += 4 + WordLength +1;
        }
        // Telegrammdaten aus Puffer entfernen
        Buffer.erase( Buffer.begin(), Buffer.begin() + TelegramLength );

        // Packet behandeln
        handle_packet( Packet );
    }
}

void receive_packets( std::vector<char>& Buffer )
{
    std::vector<char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
    if( !ReceiveBuffer.empty() )
    {
        int Received = Socket->Receive( &ReceiveBuffer[0], ReceiveBuffer.size() );
        if( Received > 0 )
        {
            TelegramBuffer.insert( Buffer.end(), ReceiveBuffer.begin(), ReceiveBuffer.begin() + Received );
            handle_packets( Buffer );
        }
    }
}

int main()
{
    std::vector<char> TelegramBuffer;

    receive_packets( TelegramBuffer );
    handle_packets( TelegramBuffer );

}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <string>
#include
<vector>
#include
<iostream>
#include
<iterator>

struct Packet
{
unsigned int Sequence;
std::vector<std::string> Words;

Packet() : Sequence( 0 )
{
}
};

void handle_packet( const Packet& Packet )
{
std::cout << "Packet Sequence : " << std::hex << "0x" << Packet.Sequence << "\n";
std::copy( Packet.Words.begin(), Packet.Words.end(), std::ostream_iterator<std::string>( std::cout, "\n" ) );
}

void handle_packets( std::vector<char>& Buffer )
{
// Telegrammlänge steht in Bytes 5-8, daher müssen mindestens
// 8 Byte im Puffer stehen

while( Buffer.size() >= 8 )
{
// Telegrammlänge bestimmen.
unsigned int TelegramLength = Buffer[4] | Buffer[5] << 8 | Buffer[6] << 16 | Buffer[7] << 24;

// stehen genügend Daten im Puffer für das komplette Telegramm? Wenn nein, dann abbrechen
if( Buffer.size() < TelegramLength ) return;

Packet Packet;

// Sequence steht in den ersten 4 Byte des Telegramms
Packet.Sequence = Buffer[0] | Buffer[1] << 8 | Buffer[2] << 16 | Buffer[3] << 24;

// Anzahl der Wörter steht in Bytes 9-12
unsigned int WordCount = Buffer[8] | Buffer[9] << 8 | Buffer[10] << 16 | Buffer[11] << 24;

// Zeiger auf Länge des 1. Wortes setzen
char* WordPtr = &Buffer[12];

// Wörter isolieren
for( unsigned int i = 0; i < WordCount; ++i )
{
// Wortlänge steht in den ersten 4 Bytes
unsigned int WordLength = WordPtr[0] | WordPtr[1] << 8 | WordPtr[2] << 16 | WordPtr[3] << 24;

// Inhalt des Strings in Paket einfügen. Inhalt des Strings steht ab Byte 4
// abschließendes Nullbyte ausnutzen, um aus char* einen std::string zu erzeugen

Packet.Words.push_back( WordPtr +4 );

// Wort überspringen (tatsächliche Wortlänge + 4 Byte für Präfix + 1 Byte abschließende 0)
WordPtr += 4 + WordLength +1;
}
// Telegrammdaten aus Puffer entfernen
Buffer.erase( Buffer.begin(), Buffer.begin() + TelegramLength );

// Packet behandeln
handle_packet( Packet );
}
}

void receive_packets( std::vector<char>& Buffer )
{
std::vector<char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
if( !ReceiveBuffer.empty() )
{
int Received = Socket->Receive( &ReceiveBuffer[0], ReceiveBuffer.size() );
if( Received > 0 )
{
TelegramBuffer.insert( Buffer.end(), ReceiveBuffer.begin(), ReceiveBuffer.begin() + Received );
handle_packets( Buffer );
}
}
}

int main()
{
std::vector<char> TelegramBuffer;

receive_packets( TelegramBuffer );
handle_packets( TelegramBuffer );

}
C/C++ Code:
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <string>
#include
<vector>
#include
<iostream>
#include
<iterator>

struct Packet
{
   unsigned int           Sequence;
   std::vector<std::string>   Words;

   Packet() : Sequence( 0 )
   {
   }        
};

void handle_packet( const Packet& Packet )
{
    std::cout << "Packet Sequence : " << std::hex << "0x" << Packet.Sequence << "\n";
    std::copy( Packet.Words.begin(), Packet.Words.end(), std::ostream_iterator<std::string>( std::cout, "\n" ) );
}

void handle_packets( std::vector<char>& Buffer )
{
    // Telegrammlänge steht in Bytes 5-8, daher müssen mindestens
    // 8 Byte im Puffer stehen

    while( Buffer.size() >= 8 )
    {
        // Telegrammlänge bestimmen.
        unsigned int TelegramLength = Buffer[4] | Buffer[5] << 8 | Buffer[6] << 16 | Buffer[7] << 24;

        // stehen genügend Daten im Puffer für das komplette Telegramm? Wenn nein, dann abbrechen
        if( Buffer.size() < TelegramLength ) return;

        Packet Packet;

        // Sequence steht in den ersten 4 Byte des Telegramms
        Packet.Sequence = Buffer[0] | Buffer[1] << 8 | Buffer[2] << 16 | Buffer[3] << 24;

        // Anzahl der Wörter steht in Bytes 9-12
        unsigned int WordCount = Buffer[8] | Buffer[9] << 8 | Buffer[10] << 16 | Buffer[11] << 24;

        // Zeiger auf Länge des 1. Wortes setzen
        char* WordPtr = &Buffer[12];

        // Wörter isolieren
        for( unsigned int i = 0; i < WordCount; ++i )
        {
            // Wortlänge steht in den ersten 4 Bytes
            unsigned int WordLength = WordPtr[0] | WordPtr[1] << 8 | WordPtr[2] << 16 | WordPtr[3] << 24;

            // Inhalt des Strings in Paket einfügen. Inhalt des Strings steht ab Byte 4
            // abschließendes Nullbyte ausnutzen, um aus char* einen std::string zu erzeugen

            Packet.Words.push_back( WordPtr +4 );

            // Wort überspringen (tatsächliche Wortlänge + 4 Byte für Präfix + 1 Byte abschließende 0)
            WordPtr += 4 + WordLength +1;
        }
        // Telegrammdaten aus Puffer entfernen
        Buffer.erase( Buffer.begin(), Buffer.begin() + TelegramLength );

        // Packet behandeln
        handle_packet( Packet );
    }
}

void receive_packets( std::vector<char>& Buffer )
{
    std::vector<char> ReceiveBuffer( Socket->ReceiveLength(), 0 );
    if( !ReceiveBuffer.empty() )
    {
        int Received = Socket->Receive( &ReceiveBuffer[0], ReceiveBuffer.size() );
        if( Received > 0 )
        {
            TelegramBuffer.insert( Buffer.end(), ReceiveBuffer.begin(), ReceiveBuffer.begin() + Received );
            handle_packets( Buffer );
        }
    }
}

int main()
{
    std::vector<char> TelegramBuffer;

    receive_packets( TelegramBuffer );
    handle_packets( TelegramBuffer );

}


Live and learn, young Padawan.

Edit:
Ohne Netz und doppelten Boden. Bei kaputten Telegrammen kann dir das um die Ohren fliegen, weil keine Plausibilitätsprüfung für Zeiger gemacht wird.

_________________
1. Dies ist die erste Regel des Tautologieclubs.


Zuletzt bearbeitet von DocShoe am 18:43:04 26.01.2012, insgesamt 2-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 19:42:37 26.01.2012   Titel:              Zitieren

Wow, das muss ich erstmal sacken lassen... Ich schreibe erst weiter wenn ich verstanden habe wo meine Fehler waren. Danke Doc
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 13:45:28 27.01.2012   Titel:              Zitieren

Mit dem linksshift war ich ja schonmal nicht ganz so falsch. Auf der rechten Seite des shifts steht die Anzahl N der Bits um die verschoben werden soll...auch noch nachvollziehbar. Ich verstehe das Bitweise OR in seiner Funktion hier einfach nicht
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 12:26:34 30.01.2012   Titel:              Zitieren

Zero01 schrieb:
Ich verstehe das Bitweise OR in seiner Funktion hier einfach nicht


Ach, komm´ schon, das ist trivial. Nimm dir´n Blatt Papier und ´nen Stift und mach´ das Ganze ein Mal von Hand. Hier die Wahrheitstabelle für OR, falls das das Problem sein sollte.

Code:
   | 0 | 1 |
---+---+---+
 0 | 0 | 1 |
---+---+---+
 1 | 1 | 1 |
---+---+---+
Code:
| 0 | 1 |
---+---+---+
0 | 0 | 1 |
---+---+---+
1 | 1 | 1 |
---+---+---+
Code:
   | 0 | 1 |
---+---+---+
 0 | 0 | 1 |
---+---+---+
 1 | 1 | 1 |
---+---+---+

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 01:47:53 31.01.2012   Titel:              Zitieren

Danke Doc :live: hab ein nettes Tutorial zum Thema Bitverschiebung gefunden und weiß jetzt, bezogen auf deine Tips, wie es verwendet wird. Ist im nachhinein auch ne klare Sache wenn ein Wert über mehrere Byte zusammenhängen geschrieben oder gelesen wird. Ich danke dir von ganzem Herzen für deine beispiellose Hilfe. Das Know How durch diesen Thread hat mich ein gutes Stück weiter gebracht
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 16:45:22 01.02.2012   Titel:              Zitieren

Hey Doc!
ich bin auf ein Problem gestossen. Wenn
die SequenceID 0x00000001 ist dann baue
ich mir doch in den stringstream ungewollt einen wertlosen stringterminator ein (0x00)
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 17:09:13 01.02.2012   Titel:              Zitieren

In meinem Code taucht nirgendwo ein stringstream auf, also musst du was dazugebastelt haben.

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 17:32:38 01.02.2012   Titel:              Zitieren

Sorry
ich meinte den ostringstream
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 17:34:00 01.02.2012   Titel:              Zitieren

Werd´ bitte mal etwas genauer, ich habe keine Ahnung, wo dein Problem liegt.

_________________
1. Dies ist die erste Regel des Tautologieclubs.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 18:23:48 01.02.2012   Titel:              Zitieren

Es geht um folgendes Statement:

You are using std::strings, and ostringstreams, to construct and contain a sequence of bytes. This works as long as you don't try to put any 0x00 bytes into the sequence. Once you start doing so, you are on very shaky ground.

Either the resulting sequence will get cut off at the first 0x00 byte, or mystring.size() will be larger than strlen(mystring.c_str()). That way lies madness and bugs that are difficult to track down.

Besides, you are aware that the 'char' datatype may be either signed or unsigned, depending on which compiler you are using? Normally it is signed. This does not cause any problems for the code that builds the sequence, but may cause problems for the code that decodes a sequence into C++ datastructures.

You are better off using an std::vector<uint8_t> as your container, dropping the ostringstream, and using some custom code for constructing the sequence.


Ist diese Aussage richtig oder falsch?
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 18:36:35 01.02.2012   Titel:              Zitieren

Es trifft hier vor allem nicht zu. Es geht darum, dass std::string durchaus Nullbytes enthalten kann und dass std::string::c_str() einen Zeiger auf einen linearen Puffer des Stringinhalts zurückgibt. Damit kommen die C-Funktionen natürlich nicht klar, aber wer Konstruktionen wie

C/C++ Code:
std::string s = "Mächtiger Badabumm";
unsigned int len = strlen( s.c_str() );
C/C++ Code:
std::string s = "Mächtiger Badabumm";
unsigned int len = strlen( s.c_str() );
C/C++ Code:
std::string s = "Mächtiger Badabumm";
unsigned int len = strlen( s.c_str() );


benutzt hat eh´ nicht mehr alle Latten am Zaun. Du solltest inzwischen gemerkt haben, dass man genau wissen muss, was man programmiert. Wenn du C++ und C Funktionen so mischst, dass Fehler entstehen, dann weißt du´s offensichtlich gerade nicht.
In dem ganzen Code, den ich hier gepostet habe, tritt der Fall nie auf. Wie kommst du also darauf?

_________________
1. Dies ist die erste Regel des Tautologieclubs.


Zuletzt bearbeitet von DocShoe am 18:37:43 01.02.2012, insgesamt 1-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 20:09:54 01.02.2012   Titel:              Zitieren

Hmmm, ich frage mich gerade warum dieser
negative Unterton. Ich habe doch nur
freundlich eine Frage gestellt, zahle
meine Steuern pünktlich und tuhe auch
sonst keiner Fliege was zu leide.

Ich wurde in einem Forum von einem
User gefragt, ob ich ein C++ Beispiel habe
um ein Paket mit den gegebenen Anforderungen zu erstellen. Als
Beispiel habe ich ihm deinen
unveränderten Code gezeigt ohne
includes und ohne main().
Daraufhin hat sich einer der
Chefentwickler von EA Games
mit dem oben genannten Statement
geäussert. Daraufhin fühlte ich
mich verunsichert und wollte
dich nochmal Fragen, Gott verzeihe.

Es geht in keinsterweisse um meinen Code.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 02:01:38 02.02.2012   Titel:              Zitieren

Ich hab jetzt einen Testcode aufgebaut um sein Statement nachzubilden. Resultat des ganzen ist, dass ich seine Befürchtung mit 0x00 in einem String egal welcher Art theoretisch nachvollziehen kann aber in der Praxis mit deinem Code vollkommen irrelevant ist.

Er schrieb folgendes:
C/C++ Code:
    // Write Sequence ID
    oss << static_cast<char>( Sequence & 0xff )
         << static_cast<char>( (Sequence >> 8) & 0xff )
         << static_cast<char>( (Sequence >> 16) & 0xff )
         << static_cast<char>( (Sequence >> 24) & 0xff );
C/C++ Code:
// Write Sequence ID
oss << static_cast<char>( Sequence & 0xff )
<< static_cast<char>( (Sequence >> 8) & 0xff )
<< static_cast<char>( (Sequence >> 16) & 0xff )
<< static_cast<char>( (Sequence >> 24) & 0xff );
C/C++ Code:
    // Write Sequence ID
    oss << static_cast<char>( Sequence & 0xff )
         << static_cast<char>( (Sequence >> 8) & 0xff )
         << static_cast<char>( (Sequence >> 16) & 0xff )
         << static_cast<char>( (Sequence >> 24) & 0xff );



That bit right there takes a 32-byte integer, splits it up into 4 bytes, and stuffs each of the 4 bytes into an ostringstream object. Raw. So if Sequence == 0x00000001, the code will be stuffing 0x00's into the ostringstream.

Also quoting from above,

C/C++ Code:
        // Write terminating 0
        oss << static_cast<char>( 0 );
C/C++ Code:
// Write terminating 0
oss << static_cast<char>( 0 );
C/C++ Code:
        // Write terminating 0
        oss << static_cast<char>( 0 );


This will clearly stuff an 0x00 into the ostringstream.

Both these code sections violate the principle: do not stuff 0x00s into strings.






Darauf hin habe ich folgendes Versucht:
C/C++ Code:
std::vector<std::string> Words;
Words.push_back("login.plainText");
Words.push_back("mypassword");
std::string Packet = make_packet( 0x00000001, Words );
C/C++ Code:
std::vector<std::string> Words;
Words.push_back("login.plainText");
Words.push_back("mypassword");
std::string Packet = make_packet( 0x00000001, Words );
C/C++ Code:
std::vector<std::string> Words;
Words.push_back("login.plainText");
Words.push_back("mypassword");
std::string Packet = make_packet( 0x00000001, Words );

.....funktioniert.

C/C++ Code:
std::string Packet = make_packet( 0x00, Words );
C/C++ Code:
std::string Packet = make_packet( 0x00, Words );
C/C++ Code:
std::string Packet = make_packet( 0x00, Words );

....funktioniert

C/C++ Code:
std::string Packet = make_packet( 1, Words );
C/C++ Code:
std::string Packet = make_packet( 1, Words );
C/C++ Code:
std::string Packet = make_packet( 1, Words );

.....funktioniert.


Zuletzt bearbeitet von Zero01 am 02:05:24 02.02.2012, insgesamt 1-mal bearbeitet
nn
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.10.2011
Beiträge: 71
Beitrag nn Mitglied 09:55:20 02.02.2012   Titel:              Zitieren

Zero01 schrieb:

Ist diese Aussage richtig oder falsch?

Beides.

std::string kann mit Nullbytes umgehen und wird auch so verwendet. Auch in gängiger C++ Fachliteratur (z.B. Scott Meyers) steht nichts darüber, dass man das nicht tun soll.

Was dieser angebliche "Chefprogrammierer" da schreibt:

Zero01 schrieb:

Both these code sections violate the principle: do not stuff 0x00s into strings.

ist eine hausinterne Regel, die jemand braucht, der so etwas wie
C/C++ Code:
unsigned int len = strlen( s.c_str() );
C/C++ Code:
unsigned int len = strlen( s.c_str() );
C/C++ Code:
unsigned int len = strlen( s.c_str() );
schreibt.

Dass der, wie DocShoe schreibt, nicht alle Latten am Zaun hat, ist Realität und kein negativer Unterton.

Auch C-Strings können Nullbytes enthalten:
C/C++ Code:
char* pc = "ABC\0abc";
C/C++ Code:
char* pc = "ABC\0abc";
C/C++ Code:
char* pc = "ABC\0abc";

Es gibt genügend Anwendungen, wo das vorkommt. Was mach der "Chefprogrammierer" dann ?


Zuletzt bearbeitet von nn am 10:15:46 02.02.2012, insgesamt 2-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1609
Beitrag DocShoe Mitglied 10:47:28 02.02.2012   Titel:              Zitieren

Jetzt fühl´ dich nicht gleich auf den Schlips getreten, ich habe weder behauptet, dass du Steuern hinterziehst noch irgendwie anders kriminell bist.
C++ ist nun mal ein Sprache, die Vieles erlaubt und damit auch viele Möglichkeiten bietet, etwas falsch zu machen. Deshalb schrieb ich ja schon mehrmals, dass man genau wissen muss, was man tut. Wenn ich weiß, dass eine Sequence Binärdaten enthält, dann sollte ich da kein strlen draufloslassen, weil eben genau der Fall eintreten kann, dass irgendwo mittendrin Nullbytes stehen. Und dann liefert strlen nicht das zurück, was man haben will. Für jedes Problem das richtige Werkzeug, und in diesem Fall ist strlen nicht das richtige Werkzeug. Im übrigen geht

C/C++ Code:
std::vector<uint_8t> MyVec = ...;
unsigned int len = strlen( &MyVec[0] );
C/C++ Code:
std::vector<uint_8t> MyVec = ...;
unsigned int len = strlen( &MyVec[0] );
C/C++ Code:
std::vector<uint_8t> MyVec = ...;
unsigned int len = strlen( &MyVec[0] );


genauso in die Hose, wenn der Vektor Nullbytes in der Mitte enthält.

Der EA Chefprogrammierer assoziiert mit std::string wohl ein gekapseltes C-String Pendant. Dabei ist std::string wesentlich mächtiger als C-Strings, und das habe ich in meinem Code bewusst ausgenutzt. Du kannst stattdessen natürlich auch einen std::vector<unsigned char> benutzen, wenn es dir besser gefällt:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
std::vector<char> Buffer;
std::string Word;

Buffer.push_back( static_cast<char>( SequenceID & 0xff ) );
Buffer.push_back( static_cast<char>( SequenceID >> 8) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 16) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 24) & 0xff );
Buffer.insert( Buffer.end(), Word.begin(), Word.end() );

...
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
std::vector<char> Buffer;
std::string Word;

Buffer.push_back( static_cast<char>( SequenceID & 0xff ) );
Buffer.push_back( static_cast<char>( SequenceID >> 8) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 16) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 24) & 0xff );
Buffer.insert( Buffer.end(), Word.begin(), Word.end() );

...
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
std::vector<char> Buffer;
std::string Word;

Buffer.push_back( static_cast<char>( SequenceID & 0xff ) );
Buffer.push_back( static_cast<char>( SequenceID >> 8) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 16) & 0xff );
Buffer.push_back( static_cast<char>( SequenceID >> 24) & 0xff );
Buffer.insert( Buffer.end(), Word.begin(), Word.end() );

...


aber da gefällt mir das ostream Interface wesentlich besser.

Mit gleichem Argument könnte ich die Benutzung von iteratoren verbieten, da dieser Code zwar kompiliert, aber zu UB führt, was ziemlich knifflig zu debuggen ist:

C/C++ Code:
std::vector<int> v =...;
std::sort( v.end(), v.begin() );
C/C++ Code:
std::vector<int> v =...;
std::sort( v.end(), v.begin() );
C/C++ Code:
std::vector<int> v =...;
std::sort( v.end(), v.begin() );

_________________
1. Dies ist die erste Regel des Tautologieclubs.


Zuletzt bearbeitet von DocShoe am 10:59:55 02.02.2012, insgesamt 1-mal bearbeitet
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 13:51:10 02.02.2012   Titel:              Zitieren

Danke Jungs für die Aufklärung. Jetzt
wo ich dagegen argumentiert habe, hüllt
sich dieser Mensch in schweigen.

Die Aufruf um den std::string als
konstanten c_string zu lesen
um die strlen zu bestimmen is eh unfug.
Wofür haben wir dann das Bordmittel
.size() was keinerlei Sprachvermischung
benötigt.

Nichts für ungut, ich war doch gar nich
sauer.
Zero01
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.08.2004
Beiträge: 309
Beitrag Zero01 Mitglied 13:52:16 02.02.2012   Titel:              Zitieren

Danke Jungs für die Aufklärung. Jetzt
wo ich dagegen argumentiert habe, hüllt
sich dieser Mensch in schweigen.

Die Aufruf um den std::string als
konstanten c_string zu lesen
um die strlen zu bestimmen is eh unfug.
Wofür haben wir dann das Bordmittel
.size() was keinerlei Sprachvermischung
benötigt.

Nichts für ungut, ich war doch gar nich
sauer.
C/C++ Forum :: VCL (C++ Builder) ::  Protokollanleitung als fertiges Paket schreiben   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.