packet



  • Hallo zusammen,

    ich hätte ein paar Fragen zu diesem Code:

    //die Struktur die als Parameter übergeben wird
    
    struct CPacket
    {
    	unsigned short size;
    	unsigned short command;
    	unsigned short unused;
    	unsigned char buffer[ 0x3FA ];  //warum ein char und kein u_short array?
    };
    
    //die funktion
    
    void logPack (char *packet)
    {
    //da packet[0] == size ist, kann ich daraus schließen 
    //dass packet[1] == command ist?
    unsigned short paksize=(*((unsigned short*)&packet[0])) - 2; //warum -2
    int i;
    
    for (i = 0 & ~15; i < paksize; i++) //warum i&~15
    {
        if  ((i & 15) == 0) //warum i&15
           printf("%04x ",i); //was genau bezweckt dieser teil der ausgabe?
        printf((i<0)?"   ":"%02x%c",(unsigned char)packet[i],((i+1)&15)?' ':'\n');
    
    }
    if ((i & 15) != 0)
        printf("\n");
    }
    

    Jetzt schon mal ein herlzliches Dankeschön für die Hilfe

    lg
    lattella



  • Der Code soll solche Hexdumps ins Logfile schreiben.
    http://www.pacificsimplicity.ca/node/90

    void logPack (char *packet)
    {
    //da packet[0] == size ist, kann ich daraus schließen
    //dass packet[1] == command ist?
    
    //weiß keiner so genau- vielleicht wird 
    //die logPack nur mit dem buffer eines Pakets aufgerufen?
    
    unsigned short paksize=(*((unsigned short*)&packet[0])) - 2; //warum -2
    //Typisch wäre am Ende des Pakets eine Checksumme, die hier keiner 
    //loggen wollte. 
    int i;
    
    for (i = 0 & ~15; i < paksize; i++) //warum i&~15
    //Das &~15 stammt aus alten Überlegungen und ist in dieser Version deplaziert. 
    {
        if  ((i & 15) == 0) //warum i&15
    //Ist gleich zu ((i %16) == 0)
    //Alle 16 Bytes soll ein Zeilenumbruch gemacht werden für den 
    //hübschen Hexdump
           printf("%04x ",i); //was genau bezweckt dieser teil der ausgabe?
    //Adresse ausgeben. Sozusagen die Zeilennummer. Genau wie im Link von mir. 
    //Vierstellig hex. 
    
        printf((i<0)?"   ":"%02x%c",(unsigned char)packet[i],((i+1)&15)?' ':'\n');
    //gamecoder mit sockenschuss. 
        printf("%02x",(unsigned char)packet[i]);
        if((i&15)==15)
           putch('\n');
    }
    //und zum Abschluss noch einen Zeilenumbruch, falls mitten in der Zeile 
    //aufgehört wurde. 
    if ((i & 15) != 0)
        printf("\n");
    }
    


  • Danke für Link, Antwort und Mühe!

    void logPack (char *packet)
    {
    //da packet[0] == size ist, kann ich daraus schließen
    //dass packet[1] == command ist?

    //weiß keiner so genau- vielleicht wird
    //die logPack nur mit dem buffer eines Pakets aufgerufen?

    //using ASIO lib
    int cpaksize=6;
    int cpakrecv=0;
    char cbuf[0x800];
    
    if (!isActive) {
    			clientsock = accept( listenersock, NULL, NULL );
    			if(!connecttorealserver(getrealhost(), getrealport())) return false;
    		}
    
    		FD_ZERO( &fds );
    		FD_SET(serversock, &fds);
    		FD_SET(clientsock, &fds);
    
    		activity = select(0, &fds, NULL, NULL, NULL);
    
    		if (FD_ISSET(clientsock, &fds)){
    			int recvsize = recv( clientsock, &cbuf[cpakrecv], cpaksize-cpakrecv, 0 );
    
    			cpakrecv += recvsize;
    
    			if (cpakrecv==6) {
    				cpaksize = *(unsigned short*)&cbuf[0];
    			}
    			if(cpakrecv==cpaksize) {
    				CPacket* pak = (CPacket*)cbuf;
    				logPack((char*) pak);
    

    Aus diesem Code schließe ich dass logPack pro Packet einmal aufgerufen wird

    unsigned short paksize=(((unsigned short)&packet[0])) - 2; //warum -2
    //Typisch wäre am Ende des Pakets eine Checksumme, die hier keiner
    //loggen wollte.

    Gut zu wissen Danke

    for (i = 0 & ~15; i < paksize; i++) //warum i&~15
    //Das &~15 stammt aus alten Überlegungen und ist in dieser Version deplaziert.

    Was wäre eine aktuelle Alternative?

    {
    if ((i & 15) == 0) //warum i&15
    //Ist gleich zu ((i %16) == 0)
    //Alle 16 Bytes soll ein Zeilenumbruch gemacht werden für den
    //hübschen Hexdump

    Gut zu wissen, darf ich davon ausgehen dass i&15 schneller ist, da es sich um eine Addition handelt?

    printf("%04x ",i); //was genau bezweckt dieser teil der ausgabe?
    //Adresse ausgeben. Sozusagen die Zeilennummer. Genau wie im Link von mir.
    //Vierstellig hex.

    Danke, anscheinend war ich blind

    printf((i<0)?" ":"%02x%c",(unsigned char)packet[i],((i+1)&15)?' ':'\n');
    //gamecoder mit sockenschuss.

    An so jemanden habe ich auch gedacht

    printf("%02x",(unsigned char)packet[i]);
    if((i&15)==15)
    putch('\n');
    }
    //und zum Abschluss noch einen Zeilenumbruch, falls mitten in der Zeile
    //aufgehört wurde.
    if ((i & 15) != 0)
    printf("\n");
    }

    Und gleich noch ein Frage:

    Warum wird in der struct ein u_char statt eines u_short Arrays verwendet?



  • lattella schrieb:

    for (i = 0 & ~15; i < paksize; i++) //warum i&~15
    //Das &~15 stammt aus alten Überlegungen und ist in dieser Version deplaziert.

    Was wäre eine aktuelle Alternative?

    for(i=0;...

    {
    if ((i & 15) == 0) //warum i&15
    //Ist gleich zu ((i %16) == 0)
    //Alle 16 Bytes soll ein Zeilenumbruch gemacht werden für den
    //hübschen Hexdump

    Gut zu wissen, darf ich davon ausgehen dass i&15 schneller ist, da es sich um eine Addition handelt?
    [/quote]
    Es handelt sich bei & um bitweises AND, während % eine Division ist.
    Solche trivialen Optimierungen hat der Compiler aber auch selber zu schaffen, dafür verschandelt man seinen Code schon lange nicht mehr.

    Warum wird in der struct ein u_char statt eines u_short Arrays verwendet?

    Warum nicht? char ist für Nutzdaten doch recht naheliegend.

    Hier mal ein Beispiel für was in so Paketen drin sein kann. Am Beispiel von Ultima-Online. http://docs.polserver.com/packets/index.php?ShowAll=1&Sort=

    struct CPacket //MS-Namenskonvention für Klassen übernommen. Komisch. 
    //struct um anzudeuten, daß sie recht dumm bleibt? Nee, gell? 
    //Vielleicht ist der ganze Code nur C und kein C++?
    {
        unsigned short size;//uint16_t war gemeint
    //Er hat sich entschieden, generell zuerst die Paketgröße zu schicken. Bei 
    //Ultima-Online ist die meistens im command gegeben. 
    //Das Extra-Schicken erlaubt es, recht bequem, sowas wie Verschlüsselung, 
    //Checksummen, Speicherallikation, zu erledigen, ohne genauer ins Paket schauen 
    //zu müssen. 
        unsigned short command;//Ebenfalls uint16_t
        unsigned short unused;//Was er damit wohl vorhat?
        unsigned char buffer[ 0x3FA ];//Und hier die Nutzdaten. 
    //Kann alles sein, eine Zeile im Chat, ein gesprochener Zauber, 
    //ein Schwerthieb, Logindaten, ein Ping-Paket, alles Mögliche halt. 
    //Aha, 0x3FA ist hex für 1024-2-2-2. 
    };
    


  • υund nochmals Danke, gefolgt von neuen Fragen:

    Hat folgender Code die gleiche funktionalität, bzw ist er halbwegs akzeptable?

    int i;
    
    for (i = 0; i < paksize; i++)
    {
        if  ((i % 16) == 0) 
           printf("%04x ",i);
    	if (i<0)
    		printf("  ");
    	else
    		printf("%02x",(unsigned char)packet[i]);
    	if ((i+1) %16)
    		printf("  ");
    	else
    		putch('\n'); 
    
    }
    if ((i & 15) != 0)
        printf("\n");
    

    //Vielleicht ist der ganze Code nur C und kein C++?

    Bis auf die verwendung der Boost library ist der Code in C geschrieben, da stimme ich dir zu, mit OOP hat das nicht viel zu tun

    unsigned short size;//uint16_t war gemeint
    //Er hat sich entschieden, generell zuerst die Paketgröße zu schicken. Bei
    //Ultima-Online ist die meistens im command gegeben.
    //Das Extra-Schicken erlaubt es, recht bequem, sowas wie Verschlüsselung,
    //Checksummen, Speicherallikation, zu erledigen, ohne genauer ins Paket schauen
    //zu müssen.

    Würde die Verwendung eines uint16_t etwas verändern?

    Danke für deine Hilfe


Anmelden zum Antworten