redhat6 64位环境下的C语言程序。
需要拼一个报文,服务端要求报文头是4字节长度。
void little_endian(const int data, unsigned char* addr)
{
addr[0] = data & 0xff;
addr[1] = (data & 0xff00) >> 8;
addr[2] = (data & 0xff0000) >> 16;
addr[3] = (data & 0xff000000) >> 24;
}
需要拼一个报文,服务端要求报文头是4字节长度。
void little_endian(const int data, unsigned char* addr)
{
addr[0] = data & 0xff;
addr[1] = (data & 0xff00) >> 8;
addr[2] = (data & 0xff0000) >> 16;
addr[3] = (data & 0xff000000) >> 24;
}
int main ()
{
//此处是包体
char* msg = “send data:abcdefg”;
int msglen = strlen(msg);
//声明发送变量 sendbuf
char sendBuf[2000] ;
memset(sendBuf, 0, sizeof(sendBuf));
//把长度int转换成4字节char, 再把包体加上
little_endian(msglen, &sendBuf[0]);
memcpy(&sendBuf[4], msg, msglen);
//问题在这能打印出来, sendbuf 的size只有1, 打印出来的sendBuf也只有一个字节
printf(“sendBuf size:%d\n”,strlen(sendBuf));
printf(“sendBuf:%s \n”,sendBuf);
}
用gdb跟了一下 little_endian(msglen, &sendBuf[0]) 转换后,sendBuf[0] 就够保存不太大的长度,
此时sendBuf[1], sendBuf[2], sendBuf[3], 还是初始化的那个状态,strlen(sendBuf) 判断时,只判断一个字节后,就遇到\0,认为字符串结束了。没办法和后边的msg连到一起。
除了 little_endian函数,用memcpy(&sendBuf[0], &msglen, 4)也试了一下,是一样的结果。
把上述的char都该成unsigned char也是一样结果
哪位老鸟帮忙定位下?谢谢
解决方案
15
little_endian(msglen, &sendBuf[0]);
第二个参数类型是unsigned char *,这个函数是把一个整数(msglen)放在sendBuf缓冲区中。
sendBuf不表示一个以\0结尾的C风格字符串!
对sendBuf执行strlen(sendBuf)是错误的。strlen只能对以\0结尾的C风格字符串操作。
后面printf %s想打印出sendBuf,也是错误的。
第二个参数类型是unsigned char *,这个函数是把一个整数(msglen)放在sendBuf缓冲区中。
sendBuf不表示一个以\0结尾的C风格字符串!
对sendBuf执行strlen(sendBuf)是错误的。strlen只能对以\0结尾的C风格字符串操作。
后面printf %s想打印出sendBuf,也是错误的。
15
printf("sendBuf size:%d\n", 4 + strlen(&sendBuf[4])); printf("sendBuf:%s \n", &sendBuf[4]); 或,打印unsigned char: int i; for (i = 0; i < 4 + msglen; ++i) { printf("%02hhX ", sendBuf[i]); } 建议:把数据包封装一下,相似: typedef struct message_s { int length; char str[2000]; } message_t; void message_dump(const message_t * msg) { printf("length=%d, str="%s"\n", msg->length, msg->str); } void message_fill(message_t * msg, const char * str) { strncpy(msg->str, str, sizeof(msg->str) - 1); msg->str[sizeof(msg->str) - 1] = "\0"; msg->length = strlen(msg->str); }