首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过一个套接字发送和接收两个结构

通过一个套接字发送和接收两个结构
EN

Stack Overflow用户
提问于 2014-04-18 04:38:44
回答 3查看 768关注 0票数 1

我有一个结构:

代码语言:javascript
复制
struct one
{
    char name[10];
    int age;
};

struct two
{
    int X;
    int Y;
};

现在我想发送这个结构,例如第一个'one',第二个'two‘和从套接字接收。

但是,如果我不知道我发送的是哪种结构(结构是“one”还是“two”),该如何接收呢?

EN

回答 3

Stack Overflow用户

发布于 2014-04-18 04:51:26

您可以向要发送的数据添加标识符:

代码语言:javascript
复制
enum StructID {
    STRUCT_ONE,
    STRUCT_TWO,
};

然后在你发送数据之前发送它。

代码语言:javascript
复制
Uint16     id;
struct one dataOne;

id = STRUCT_ONE;
send(&id, sizeof(id));
send(&dataOne, sizeof(dataOne));

在接收端:

代码语言:javascript
复制
char buffer[256];
unsigned nbRecv;

nbRecv = recv(buffer, sizeof(buffer));
if (nbRecv > sizeof(Uint16))
{
    char * p = buffer;

    Uint16 *pId = (Uint16*)p;
    p += sizeof(*pId);

    if (*pId == STRUCT_ONE)
    {
        struct one * pOne = (struct one *)p;
        p += sizeof(*pOne);

        if (nbRecv >= sizeof(*pId) + sizeof(*pOne))
        {
           // deal with pOne.
        }
        else
        {
           // Deal with too little data; pOne is incomplete....
        }
    }
    else if (*pId == STRUCT_TWO)
    {
        struct two * pTwo = (struct two *)p;
        p += sizeof(*pTwo);

        if (nbRecv >= sizeof(*pId) + sizeof(*pTwo))
        {
           // deal with pOne.
        }
        else
        {
           // Deal with too little data; pTwo is incomplete....
        }
    }
    else
    {
        // Error, unknown data.
    }
}
else
{
    // Deal with too little data....
}

从本质上讲,此时您正在定义一个协议,而标识符只是一个非常简单的“头”,用于标识您的数据。很多这样的协议也会发送数据的大小,这样你就可以知道在下一个标识符/报头之前有多少数据。

除了整数之外,另一种常见的方法是发送4个ASCII字符,因为在查看原始数据(Wireshark、十六进制转储、调试器中的字节等)时,这些字符很容易读取。对于您的示例,我建议:

代码语言:javascript
复制
const char STRUCT_ONE_FOURCC[4] = { 'O', 'N', 'E', ' ' };
const char STRUCT_ONE_FOURCC[4] = { 'T', 'W', 'O', ' ' };

(请注意,它们不是字符串本身,因为它们不是NULL终止的。它们是固定大小的字符数组。)

注意:在上面的代码中,我省略了大多数错误检查和字节顺序交换(与网络字节顺序互换)。

另请参阅:

  • http://en.wikipedia.org/wiki/FourCC
  • http://www.martinreddy.net/gfx/2d/IFF.txt
票数 4
EN

Stack Overflow用户

发布于 2014-04-18 04:55:50

您需要执行序列化,添加一个标识符。一个(不是那么)简单的解决方案是:

代码语言:javascript
复制
template<int index>
struct serializable {
  static const int identifier = index;
}

struct A :
  public serializable<1>
{
  int a, b;
  char * serialize() { char *buffer = new char[sizeof (A) + sizeof (int)]; memcpy(buffer, this, sizeof(A)); }
  static A deserialize(const char *in) { return A{&in[sizeof(int)], &in[sizeof(int) * 2]}; }
}
票数 0
EN

Stack Overflow用户

发布于 2014-05-01 05:44:36

您应该定义一个在通信中使用的协议,不要发送struct,因为不同系统中的数据类型和内存对齐方式不同。您可以改用xml,序列化结构并发送xml字符串。还要检查通过TCP实现通信协议的不同库。例如,您可以检查Apache Axis。对于手动序列化,您可以使用boost::serialization并将结构转换为xml字符串。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23142997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档