为什么 memcpy 无法正常运行?

发布于 2024-09-27 05:21:40 字数 1750 浏览 1 评论 0原文

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

谢谢,

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

I have a class for an RDT Header that holds information for an implementation of several reliable data transfer protocols. I need to attach that information (a total of 12 bytes) to my send buffer to transfer it over the socket. I am trying to use memcpy to do this but for some reason it just leaves junk inside the buffer. Below is the line of code that isnt working. (RDT_HDR_SIZE is defined as 12).

Definition of variables that are passed to this function.

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];

The function with memcpy that is having issues.

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

If i take out RDT_HDR_SIZE, the payload is assigned properly to buf, however it wipes out all my header fields. Any idea how to get this to work?

Thanks,

Eric R.

EDIT:

Here is the code for my RdtHeader class -- perhaps it will be of use.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清秋悲枫 2024-10-04 05:21:41

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

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

As Mark said, look at sizeof(RdtHeader). There might be some padding inside the struct (especially since there is a long int there) that throws the calculations off.

But other than that, I don't see an obvious problem here. I would try to add some print-outs, if you're running it in an environment where that is feasible, or try a debugger. Possibly the real problem is elsewhere in your code.

另类 2024-10-04 05:21:41
memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • 你神秘地返回了一个
    额外的1,表明有效负载是
    以 null 结尾的字符串。你可能会
    想要复制那个终结符,所以它是
    包含在最后一个memcpy
    范围。
  • 通过使用 header 指针来计算 memcpy 目标,如果类型发生变化,特别是当您更改 buf 的类型时,您将永远不必进行强制转换。您可以相信 C++ 允许 X * 降级为 void * 以避免丑陋的转换。
memcpy(header + 1, payload, payload_size + 1);
return sizeof(*header) + payload_size + 1;
  • You're mysteriously returning an
    extra 1, suggesting the payload is
    a null-terminated string. You might
    want to copy that terminator, so it's
    included in the last memcpy
    parameter.
  • By using the header pointer to calculate the memcpy destination, you'll never have to cast if types change, in particular if you change the type of buf. You can rely on the fact that C++ allows X * to degrade to void * to avoid ugly casting.
南巷近海 2024-10-04 05:21:40

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

你尝试过吗

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

如果您正在做……

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

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

干杯& hth.,

– 阿尔夫

This may be too obvious, but exactly how are you inspecting the buffer?

Have you tried

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

?

If you instead are doing ...

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

... then you should expect to see just garbage (with correct operation) since the win field acts as zero-terminator for the "string" that that latter call is printing.

Cheers & hth.,

– Alf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文