use*_*995 0 c++ sockets struct
我有一个结构:
struct one
{
char name[10];
int age;
};
struct two
{
int X;
int Y;
};
Run Code Online (Sandbox Code Playgroud)
现在我想发送这个结构,例如第一个“一”,第二个“二”并从套接字接收。
但是,如果我不知道发送哪个结构(结构“一”或“二”),如何接收它?
您可以将标识符添加到您发送的数据中:
enum StructID {
STRUCT_ONE,
STRUCT_TWO,
};
Run Code Online (Sandbox Code Playgroud)
并在发送数据之前发送该信息。
Uint16 id;
struct one dataOne;
id = STRUCT_ONE;
send(&id, sizeof(id));
send(&dataOne, sizeof(dataOne));
Run Code Online (Sandbox Code Playgroud)
在接收端:
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....
}
Run Code Online (Sandbox Code Playgroud)
本质上,您此时正在定义一个协议,而标识符只是一个非常简单的“标头”,用于识别您的数据。许多像这样的协议也会发送要遵循的数据大小,以便您可以知道下一个标识符/标头之前有多少数据。
除了整数之外的另一种常见方法是发送 4 个 ASCII 字符,因为当您查看原始数据(Wireshark、hexdump、调试器中的字节等)时,它们很容易读取。对于你的例子我建议:
const char STRUCT_ONE_FOURCC[4] = { 'O', 'N', 'E', ' ' };
const char STRUCT_ONE_FOURCC[4] = { 'T', 'W', 'O', ' ' };
Run Code Online (Sandbox Code Playgroud)
(注意,它们不是字符串,因为它们不是 NULL 终止的。它们是固定大小的字符数组。)
注意:在上面的代码中,我省略了大部分错误检查和字节序交换(到/从网络字节顺序)。
也可以看看: