سؤال

لدي فئة لرأس RDT الذي يحمل معلومات لتنفيذ العديد من بروتوكولات نقل البيانات الموثوقة. أحتاج إلى إرفاق تلك المعلومات (ما مجموعه 12 بايت) إلى المخزن المؤقت لإرسالها لنقلها إلى المقبس. أحاول استخدام Memcpy للقيام بذلك ، لكن لسبب ما يترك غير مرغوب فيه داخل المخزن المؤقت. فيما يلي سطر الكود الذي لا يعمل. (يتم تعريف RDT_HDR_SIZE على أنه 12).

تعريف المتغيرات التي يتم تمريرها إلى هذه الوظيفة.

char payload[] = "sample code sample code";
int payload_size = sizeof(payload) ; 
int pktsize = payload_size + sizeof( RdtHeader )+1 ; // 1 byte for NULL-terminated
char * send_buf = new char[pktsize];

الوظيفة مع memcpy التي لديها مشاكل.

unsigned int Sender::CreateSegment( char * buf, 
         char payload[], int payload_size, unsigned long seqnum ) {
     RdtHeader * header = (RdtHeader *) buf; 
     // set rdt fields:
     header->ack = 0; 
     header->fin = 0; 
     header->ok = 0; 
     header->seq = seqnum; 
     header->win = 0;
     header->syn = 0;
     memcpy( buf+RDT_HDR_SIZE, payload, payload_size );

     return (payload_size + RDT_HDR_SIZE + 1);
}

إذا أخرجت RDT_HDR_SIZE ، يتم تعيين الحمولة النافعة بشكل صحيح إلى BUF ، ومع ذلك فإنه يمسح جميع حقول HELDER. أي فكرة عن كيفية عمل هذا؟

شكرًا،

إريك ر.

تعديل:

فيما يلي رمز فئة RDTheader الخاصة بي - ربما سيكون مفيدًا.

class RdtHeader{    // 12-byte header 
public: 
//1-byte flags field
    u_char protocol:2;      // 2 bits: protocol type = 0 for RDT3, 1 for GBN, and 2 for STCP    
    u_char syn:1;           // 1 bit: SYN = 1 for connection setup  
    u_char fin:1;           // 1 bit: FIN = 1 for termination
    u_char ok:1;            // 1 bit: OK = 1 receiver agrees, SYN_OK or FIN_OK
    u_char reserved:3;      // 3 bits: unused

    u_char unused;          // 1-byte unused filed; 

    u_short win;            // 2-byte receiver window size (the number of packets)
    u_long seq;             // 4-byte sequence number
    u_long ack;             // 4-byte ack number
}; 
هل كانت مفيدة؟

المحلول

قد يكون هذا واضحًا جدًا ، ولكن بالضبط كيف تقوم بفحص المخزن المؤقت؟

هل جربت

printf( "%s\n", send_buf + sizeof(RdtHeader) );

?

إذا كنت تفعل ...

printf( "%s\n", send_buf );

... ثم يجب عليك توقع لرؤية القمامة فقط (مع التشغيل الصحيحة) منذ win يعمل الحقل كمصفة صفرية لـ "السلسلة" التي تتمثل هذه المكالمة الأخيرة في الطباعة.

هتاف و هول. ،

- ألف

نصائح أخرى

كما قال مارك ، انظر إلى Sizeof (RdTheader). قد يكون هناك بعض الحشوة داخل البنية (خاصة وأن هناك int طويلة هناك) التي تطرد الحسابات.

لكن بخلاف ذلك ، لا أرى مشكلة واضحة هنا. سأحاول إضافة بعض المطبوعات ، إذا كنت تقوم بتشغيلها في بيئة يكون فيها هذا ممكنًا ، أو جرب تصحيح الأخطاء. ربما المشكلة الحقيقية هي في مكان آخر في الكود الخاص بك.

memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • أنت تعود بشكل غامض إلى إضافي 1, ، مما يشير إلى أن الحمولة هي سلسلة من إنهاء الفرق. قد ترغب في نسخ هذا المنهي ، لذلك يتم تضمينه في آخر memcpyمعامل.
  • باستخدام header مؤشر لحساب وجهة memcpy ، لن تضطر أبدًا إلى الإلقاء إذا تغيرت الأنواع ، ولا سيما إذا قمت بتغيير نوع buf. يمكنك الاعتماد على حقيقة أن C ++ يسمح X * لتتحول إلى void * لتجنب الصب القبيح.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top