为什么 memcpy 无法正常运行?
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如马克所说,看看 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.
额外的
1
,表明有效负载是以 null 结尾的字符串。你可能会
想要复制那个终结符,所以它是
包含在最后一个
memcpy
中范围。
X *
降级为void *
以避免丑陋的转换。extra
1
, suggesting the payload isa null-terminated string. You might
want to copy that terminator, so it's
included in the last
memcpy
parameter.
header
pointer to calculate the memcpy destination, you'll never have to cast if types change, in particular if you change the type ofbuf
. You can rely on the fact that C++ allowsX *
to degrade tovoid *
to avoid ugly casting.这可能太明显了,但是您到底如何检查缓冲区呢?
你尝试过吗
?
如果您正在做……
那么您应该期望看到垃圾(正确操作),因为
win
字段充当“的零终止符” string”,后一个调用正在打印。干杯& hth.,
– 阿尔夫
This may be too obvious, but exactly how are you inspecting the buffer?
Have you tried
?
If you instead are doing ...
... 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