سؤال

وكيفية الحصول على طول حزمة UDP المستلمة؟ باستخدام يريشارك كنت أرى طول الصحيح من مخطط البيانات. كيف يمكنني طباعة هذه القيمة في برنامجي الخادم UDP بسيط؟ وأنا أتلقى البيانات الثنائية (أحرف ASCII غير القابلة للطباعة باعتباره البيانات) لذلك لا أستطيع استخدام strlen (BUF) الذي يلقي طول غير صحيح.

      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 طول الحزمة هو دائما "0" من رمز أعلاه. أي تعليقات؟

وأنا أيضا حاولت مثل أدناه

         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)));
         }

ورمز أعلاه يعود لي دائما قيم خاطئة من رأس الملكية الفكرية؟ أي تعليقات؟

ويتم تضمين الملف C الأصلي هنا.

#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;
}

وإخراج أنا receivingis كما يلي:

 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 

ما سبق فك شفرة البيانات المتطابقة مع البيانات المرسلة بلدي.

هل كانت مفيدة؟

المحلول

وكيف خلق المقبس الخاص بك؟ هو مأخذ الخام (SOCK_RAW) أو مأخذ dgram (SOCK_DGRAM)؟ في الحالة الثانية، فإنك لن تحصل على الملكية الفكرية / UDP رؤوس، حمولة فقط.

وبالمناسبة، طول الحزمة هو القيمة التي تم إرجاعها من recvfrom وظيفة - في قضيتك، و "المتقاعد" متغير. تحقق recvfrom الصفحة رجل.

نصائح أخرى

والإجابة القصيرة (على الرغم من أنه هو بالفعل في التعليقات أعلاه): recvfrom إرجاع عدد البايتات الواردة.

والمشكلة هنا هو:

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

وإعادة كتابة ذلك على النحو التالي:

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

وأرجع سوف تحتوي على عدد من وحدات البايت

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top