3

我有一个用于 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,但它会清除我所有的标头字段。知道如何让它工作吗?

谢谢,

埃里克·R。

编辑:

这是我的 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
}; 
4

3 回答 3

2

正如马克所说,看看 sizeof(RdtHeader)。结构内部可能有一些填充(特别是因为那里有一个 long int),这会导致计算中断。

但除此之外,我在这里没有看到明显的问题。如果您在可行的环境中运行它,我会尝试添加一些打印输出,或者尝试使用调试器。可能真正的问题在您的代码中的其他地方。

于 2010-10-12T04:35:00.780 回答
2

这可能太明显了,但是您究竟是如何检查缓冲区的呢?

你有没有尝试过

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

?

相反,如果您正在做...

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

...那么您应该期望看到垃圾(使用正确的操作),因为该win字段充当后一个调用正在打印的“字符串”的零终止符。

干杯&hth.,

– 阿尔夫

于 2010-10-12T05:36:48.257 回答
0
memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • 您神秘地返回了一个 extra 1,表明有效负载是一个以 null 结尾的字符串。您可能想要复制该终止符,因此它包含在最后一个memcpy 参数中。
  • 通过使用header指针来计算 memcpy 目标,如果类型更改,您将永远不必强制转换,特别是如果您更改buf. 您可以依靠 C++ 允许X *降级void *以避免丑陋的转换这一事实。
于 2010-10-12T04:39:13.827 回答