通过用C套接字传递的结构 [英] Passing a structure through Sockets in C

查看:140
本文介绍了通过用C套接字传递的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从客户整体结构传递给服务器或反之亦然。让我们假设我的结构如下:

I am trying to pass whole structure from client to server or vice-versa. Let us assume my structure as follows

struct temp {
  int a;
  char b;
}

我使用的 SENDTO 并发送结构变量的地址,并使用 recvfrom的函数接收它的另一面。但我不能够获得在接收端发送的原始数据。在SENDTO功能,我接收到的数据保存到类型结构温度的变化。

I am using sendto and sending the address of the structure variable and receiving it on the other side using the recvfrom function. But I am not able to get the original data sent on the receiving end. In sendto function I am saving the received data into variable of type 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的类型结构温度的变化。

Where pkt is the variable of type struct temp.

Eventhough我接收数据的8个字节,但如果我尝试打印,它只是显示垃圾值。关于它修复任何帮助吗?

Eventhough I am receiving 8bytes of data but if I try to print it is simply showing garbage values. Any help for a fix on it ?

注意: 中使用任何第三方库有

EDIT1:我真的很新的这系列化概念。但没有做系列化着我通过套接字发送一个结构

I am really new to this serialization concept .. But without doing serialization cant I send a structure via sockets ?

EDIT2:当我尝试使用发送字符串或整数变量在 SENDTO recvfrom的功能,我收到了在正确接收端的数据。为什么不能在一个结构的情况下?如果我没有使用序列化功能的话,我应该把每单独结构的每个成员?这实在不是一个合适的解决方案,因为如果有N的成员数量则有增加code线的'N'号只是为了发送或接收数据。

When I try to send a string or an integer variable using the sendto and recvfrom functions I am receiving the data properly at receiver end. Why not in the case of a structure? If I don't have to use serializing function then should I send each and every member of the structure individually? This really is not a suitable solution since if there are 'n' number of members then there are 'n' number of lines of code added just to send or receive data.

推荐答案

这是一个非常糟糕的主意。二进制数据应该总是在某种程度上被发送的是:

This is a very bad idea. Binary data should always be sent in a way that:


  • 处理不同的字节顺序

  • 处理不同的<一个href=\"http://en.wikipedia.org/wiki/Data%5Fstructure%5Falignment#Data%5FStructure%5FPadding\">padding

  • 把手在字节大小

  • Handles different endianness
  • Handles different padding
  • Handles differences in the byte-sizes of intrinsic types

永远不要写一个整体结构以二进制的方式,而不是一个文件,不是一个套接字。

Don't ever write a whole struct in a binary way, not to a file, not to a socket.

总是分开来写每个字段,并阅读他们以同样的方式。

Always write each field separately, and read them the same way.

您需要有这样的功能。

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);

或者相当于当然有几种方法与问候设置此缓冲管理等等。然后,你需要做的序列化/反序列化整个结构更高级别的功能。

Or the equivalent, there are of course several ways to set this up with regards to buffer management and so on. Then you need to do the higher-level functions that serialize/deserialize entire structs.

此假设串行化完成向/从缓冲器,这意味着该序列并不需要知道,如果最终目的地是一个文件或一个插座。这也意味着你付出一些内存开销,但它通常是出于性能方面的一个好的设计(你不想做的每个值插座的写())。

This assumes serializing is done to/from buffers, which means the serialization doesn't need to know if the final destination is a file or a socket. It also means you pay some memory overhead, but it's generally a good design for performance reasons (you don't want to do a write() of each value to the socket).

一旦你有以上,这里是你如何可以序列和传输结构实例:

Once you have the above, here's how you could serialize and transmit a structure instance:

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;
}

有几点需要注意上述:

A few points to note about the above:


  • 要发送的结构是第一序列,逐个字段,为缓存

  • 序列化程序返回缓冲区中的指针指向下一个空闲的字节,我们利用计算它有多少字节序列化到

  • 显然,我的例子序列化程序不能防止缓冲区溢出。

  • 返回值是1,如果的sendto()调用成功,否则这将是0。

  • The struct to send is first serialized, field by field, into buffer.
  • The serialization routine returns a pointer to the next free byte in the buffer, which we use to compute how many bytes it serialized to
  • Obviously my example serialization routines don't protect against buffer overflow.
  • Return value is 1 if the sendto() call succeeded, else it will be 0.

这篇关于通过用C套接字传递的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆