Question

Comment obtenir la longueur du paquet UDP reçu? En utilisant Wireshark je pouvais voir la longueur correcte de datagrammes. Comment puis-je imprimer cette valeur dans mon programme simple serveur udp? Je reçois des données binaires (caractères ascii non imprimables comme données) Je ne peux pas utiliser strlen (BUF) qui jette une longueur incorrecte.

      if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1){
            error = ioctl(s, FIONREAD, &value);
            printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error);
      }

udp longueur du paquet est toujours « 0 » du code ci-dessus. Tous les commentaires?

J'ai essayé aussi comme ci-dessous

         if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)!=-1){
            unsigned short iphdrlen;
            struct iphdr* iph = (struct iphdr*)buf;
            iphdrlen =iph->ihl*4;

            printf("IP version :%d\n", ((unsigned int)((iph->version))));
            printf("protocol .. %d\n", ((unsigned int)(iph->protocol)));
            printf("total len .. %d\n", (ntohs(iph->tot_len)));
         }

Le code ci-dessus me renvoie toujours mal les valeurs de tête ip? Tous les commentaires?

Le fichier d'origine C est inclus ici.

#include "udp_common.h"

int main(void)
{
        struct sockaddr_in si_me, si_other;
        int s, i, slen=sizeof(si_other);
        unsigned char buf[BUFLEN];
        int noofbytes=0;
        int ret=0,error,value;

        memset(buf, 0, 512);
        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
                diep("socket");

        memset((char *) &si_me, 0, sizeof(si_me));
        si_me.sin_family = AF_INET;
        si_me.sin_port = htons(PORT);
        si_me.sin_addr.s_addr = htonl(INADDR_ANY);
        if (bind(s, (struct sockaddr *)&si_me, sizeof(si_me))==-1)
                diep("bind");

        for (i=0; ; i++)
        //for (i=0; i<NPACK ; i++) 
        {
                if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1)
                diep("recvfrom()");
                printf(" source port is : %d %d\n", ntohs(si_other.sin_port), slen);

                unsigned short iphdrlen;
                struct iphdr* iph = (struct iphdr*)buf;
                iphdrlen =iph->ihl*4;

                printf("IP version :%d\n", ((unsigned int)((iph->version))));
                printf("protocol .. %d\n", ((unsigned int)(iph->protocol)));
                printf("total len .. %d\n", (ntohs(iph->tot_len)));
                error = ioctl(s, FIONREAD, &value);
                printf(" from ioctl UDP packet length is : %d error is : %d\n", value, error);
                printf(" Return code from recvfrom is : %d\n", ret);
                printf("Received packet from %s:%d\nData: %s\n\n",
                inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);

                int j=0;
                for ( j = 0; j <20; j++)
                {
                        char x = buf[j];
                        short int i;
                        for (i=1;i<9;i++)
                        {
                                ((x | (1<<8-i)) == x)?printf("1"):printf("0");
                        }
                        printf(" ");
                }
                printf("\n");
        }


        close(s);
        return 0;
}

Et la sortie, je suis receivingis comme suit:

 source port is : 4232 16
IP version :1
protocol .. 65
total len .. 4096
 from ioctl UDP packet length is : 0 error is : 0
 Return code from recvfrom is : 0
Received packet from 127.0.0.1:4232
Data: 

00010000 00000001 00010000 00000000 11110001 00010001 00010001 00100100 01000100 01000001 00010001 00100100 01000100 01000000 00000000 00010000 00000000 00010000 10100000 10100000 

Les données ci-dessus correspondent décryptées avec mes données envoyées.

Était-ce utile?

La solution

Comment avez-vous créé votre prise? Est-ce une raw socket (SOCK_RAW) ou une prise dgram (SOCK_DGRAM)? Dans le second cas, vous ne serez pas ip / têtes udp, seule la charge utile.

Par ailleurs, la longueur du paquet est la valeur renvoyée de la fonction recvfrom - dans votre cas, la variable « ret ». Consultez recvfrom de l'homme.

Autres conseils

Réponse courte (bien qu'il soit déjà dans les commentaires ci-dessus): recvfrom retourne le nombre d'octets reçus.

problème ici est:

if (ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)==-1)

réécrire comme:

ret=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *)&si_other, &slen)
if (ret==-1)
{
}

ret contiendra le nombre d'octets

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top