转载请注明出处
作者:小马
今天写一个基于TCP/IP的数据包发送程序时, 遇到一个问题, 我发送了一个数据包过去, 服务端可以接收到,但接收到的数据长度小于我实际传送的数据长度. 这个bug调了很久, 开始还认为是服务器端的程序问题, 最终发现是栽在了指针上面.
发送数据包的包格式形如下面的定义:
- typedef struct _TestStruct
- {
- char testA[5];
- char *pTest;
- char testC[4];
- }TestStruct_s;
因为,pTest域的大小是可变的, 需要动态分配. 所以我把它置成指针. 然后我对数据包赋值
- TestStruct_s testData;
- memcpy(testData.testA, "abcde", 5);
- testData.pTest = (char *)malloc(sizeof(char)*3);
- memcpy(testData.pTest, "fgh", 3);
- memcpy(testData.testC, "ijkl", 4);
接着调用一个socket发送函数把这个包发送出去, 该函数接收两个参数, 一个要发送的字符串缓冲区,一个是缓冲区长度. 所以我先把组好的数据包复制到一个临时缓冲区里.
- <span style="color:#000000;"></span>
- <span style="color:#000000;">char sendBuffer[1024] = {0};
- char sendLen = 12;
- memcpy(sendBuffer, &testData, sendLen);</span> //这一步出现了致命的错误.
我想当然的以为sendBuffer应该是”abcdefghijkl”了, 所以我调用socket_send函数发送数据到服务器.
socket_send(sendBuffer, sendLen);
相信高手应该已经看出来我的问题在哪里了. 因为memcpy是复制连续的内存, 但是testData的数据并不是连续的, 因为pTest域是
testData.pTest = (char *)malloc(sizeof(char)*3)动态分配的.
单步跟一下内存如下图所示:
0x0012fb80是sendBuffer的内存地址, 可以看出, 到第三个CC后面的00,sendBuffer就已经束了, 因为字符串是以0x00结尾的, memcpy在执行的时候, 只复制到这里就结束了.