c - 在 C 中通过套接字传递结构

标签 c sockets recv sendto

我正在尝试将整个结构从客户端传递到服务器,反之亦然。让我们假设我的结构如下

struct temp {
  int a;
  char b;
}

我正在使用 sendto 并发送结构变量的地址并使用 recvfrom 函数在另一端接收它。但是我无法获得接收端发送的原始数据。在 sendto 函数中,我将接收到的数据保存到 struct temp 类型的变量中。

n = sendto(sock, &pkt, sizeof(struct temp), 0, &server, length);
n = recvfrom(sock, &pkt, sizeof(struct temp), 0, (struct sockaddr *)&from,&fromlen);

其中 pkt 是 struct temp 类型的变量。

尽管我收到了 8 字节的数据,但如果我尝试打印它,它只会显示垃圾值。对修复它有什么帮助吗?

注意: 无需使用第三方库。

EDIT1:我对这个序列化概念真的很陌生。但是如果不进行序列化,我就不能通过套接字发送结构吗?

EDIT2: 当我尝试使用 sendtorecvfrom 功能我在接收端正确接收数据。为什么不在结构的情况下?如果我不必使用序列化函数,那么我应该单独发送结构的每个成员吗?这确实不是一个合适的解决方案,因为如果有 'n' 个成员,那么就会添加 'n' 行代码来发送或接收数据。

最佳答案

这是一个非常糟糕的主意。二进制数据应始终以以下方式发送:

永远不要以二进制方式写入整个结构,不要写入文件,也不要写入套接字。

始终分别编写每个字段,并以相同的方式读取它们。

你需要有这样的功能

unsigned char * serialize_int(unsigned char *buffer, int value)
{
  /* Write big-endian int value into buffer; assumes 32-bit int and 8-bit char. */
  buffer[0] = value >> 24;
  buffer[1] = value >> 16;
  buffer[2] = value >> 8;
  buffer[3] = value;
  return buffer + 4;
}

unsigned char * serialize_char(unsigned char *buffer, char value)
{
  buffer[0] = value;
  return buffer + 1;
}

unsigned char * serialize_temp(unsigned char *buffer, struct temp *value)
{
  buffer = serialize_int(buffer, value->a);
  buffer = serialize_char(buffer, value->b);
  return buffer;
}

unsigned char * deserialize_int(unsigned char *buffer, int *value);

或者等价物,当然有几种方法可以在缓冲区管理等方面进行设置。然后您需要执行更高级别的函数来序列化/反序列化整个结构。

这假设序列化是对缓冲区进行的/从缓冲区完成的,这意味着序列化不需要知道最终目标是文件还是套接字。这也意味着您需要付出一些内存开销,但出于性能原因,这通常是一个不错的设计(您不想对套接字执行每个值的 write())。

完成上述操作后,您可以按照以下方式序列化和传输结构实例:

int send_temp(int socket, const struct sockaddr *dest, socklen_t dlen,
              const struct temp *temp)
{
  unsigned char buffer[32], *ptr;

  ptr = serialize_temp(buffer, temp);
  return sendto(socket, buffer, ptr - buffer, 0, dest, dlen) == ptr - buffer;
}

以上几点需要注意的地方:

  • 首先将要发送的结构逐个序列化到 buffer 中。
  • 序列化例程返回指向缓冲区中下一个空闲字节的指针,我们用它来计算序列化到多少字节
  • 显然,我的示例序列化例程无法防止缓冲区溢出。
  • 如果 sendto() 调用成功,返回值为 1,否则为 0。

关于c - 在 C 中通过套接字传递结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1577161/

相关文章:

c - 如何减少代码中的 for 循环数量

c# - 如何为包含 ManualResetEvent.WaitOne() 的异步(套接字)代码编写单元测试?

c - 处理坏文件描述符错误的方法

python - 类型错误 : Can't convert 'bytes' object to str implicitly while working with sockets

c - Fwrite 到位图文件导致无限循环

c++ - 将 OLECHAR* 转换为 CHAR* 以构建 string()

Python套接字: Server side not responding after the input of list

Python Socket recvfrom() 超时?

c - 机器代码指令如何传输到 CPU?

c - 套接字卡在 CLOSE_WAIT 状态