通过UDP套接字后解压缩的结构

时间:2013-09-16 14:39:01

标签: c sockets struct udp

我有一些代码可以将UDP套接字发送到服务器。目前我有一个单独的服务器代码,我在本地运行,它读取发送给它的任何内容,并准确回写它收到的内容。

我需要做的下一步是发送和接收结构。我可以发送结构很好,但是当我从服务器收回它时,它被混淆了。这是我的代码:

typedef struct {
 char first_part[4];
 char second_part;
 char third_part[2];
} Cloud;

然后在main

char reply[BUFLEN], message[BUFLEN];
Cloud data;

strcpy(data.first_part, "test");
data.second_part = 'a';
strcpy(data.third_part, "hi");

printf("Size:%d\n", sizeof(data));

//This part seems to work---
char* package;
package = (unsigned char*)malloc(sizeof(data));
memcpy(package, &data, sizeof(data));
printf("Size:%d\n", strlen(package));
strcpy(message, package);

udp_send_receive(message,reply);
//---So the message is sent, and the string received by the server is correct.

memcpy(package, message, strlen(message));
printf("Package: %s\n",package); //-This is also correct

memcpy(&data, package, sizeof(data));

printf(data.first_part); //--This is incorrect

如果有人能解释这里出了什么问题我真的很感激。我对这类事情缺乏经验,我的任务是构建一个与另一台服务器通信的UDP服务器,数据以特定的结构传输。

3 个答案:

答案 0 :(得分:1)

对于您认为不正确的特定行,您printf上的data.first_part不能,因为它不是以空值终止的。您需要将这四个字节(使用例如memcpy)复制到另一个长度为5个字节的缓冲区中,并确保它以空值终止。

但是,这同样适用于您之前对strXXX()的每次调用,例如strcpy(data.first_part, "test")strlen(package)strcpy(message, package)strlen(message)等等 - 这些函数必须用于以空字符结尾的字符串,而不是任意内存缓冲区,例如:

Cloud data, reply;

memcpy(data.first_part, "test", 4);  // not strcpy, it might overwrite .second_part
memcpy.second_part = 'a';
memcpy(data.third_part, "hi", 2); // not strcpy, it will overwrite the next value on the stack!

// no need to copy for transmission and receipt, BTW!
udp_send_receive(&data, &reply);

// copy reply data into a null-terminated string buffer
char tmp[5];
memcpy(tmp, reply.first_part, 4);
tmp[4] = '\0';

printf("%s\n", tmp); // should be fine!

答案 1 :(得分:1)

在C中,字符串需要\0结尾。

因此,如果您想存储“test”,则需要char first_part[5]变量。 对于需要3个字节长的third_part来存储“hi”+'\ 0'。

答案 2 :(得分:1)

关于代码的几点:

  1. 这:strcpy(data.first_part, "test");是缓冲区溢出,因为first_part只有4个字符长。 strcpy()将写一个额外的终止字符,因为它正在复制整个字符串。如果您不想使用以0结尾的字符串,请使用memcpy()
  2. 这:package = (unsigned char*)malloc(sizeof(data));drop the cast
  3. 此外,sizeof(data)更简单,可以写成sizeof data