【问题标题】:send/receive a struct with TCP/IP socket on windows 7 64bit在 Windows 7 64 位上使用 TCP/IP 套接字发送/接收结构
【发布时间】:2014-04-03 06:17:26
【问题描述】:

在这里搜索我的问题时,我发现了更多关于此的讨论,但似乎解决方案对于发送带有套接字的结构并不简单。

我不明白如何在安全模式下使用套接字发送结构。

我需要使用 struct 发送我的信息,并正确接收它,而不会丢失任何数据。

所以,情况是这样的:客户端必须向服务器发送这个结构:

typedef array<array<double,4>,4> Matrix4x4;

struct data
{
       bool shot;
       Matrix4x4 position;
};

Matrix4x4 是这样的:

Matrix4x4 T1 = {{
        {{-1.0000,   0.0000,  -0.0000,   0.1531}},
        {{0.0000,   0.0000,  -1.0000,   0.1502 }},
        {{-0.0000,  -1.0000,  -0.0000,   1.0790}},
        {{0 ,       0,        0,   1.0000    }} }}; 

每一个要发送的数据包,矩阵都改变了,布尔值是真还是假;我需要接收它并且可以访问布尔和矩阵。

我正在使用 PraticalSocket 类

http://cs.baylor.edu/~donahoo/practical/CSockets/practical/

用于在 64 位 Windows 7 上发送/接收,在 64 位项目上使用 Visual C++ 2010。

为了发送结构,我这样做:

#include "PracticalSocket.h"
#include <iostream>
#include <array>
#include <vector>
#include <Windows.h>
#include <cstdlib>


using namespace std;

#define servAddress "192.168.0.117"
const unsigned short SOCKET_SERVER_PORT = 27500;

typedef array<array<double,4>,4> Matrix4x4;

Matrix4x4 T1 = {{
    {{-1.0000,   0.0000,  -0.0000,   0.1531}},
    {{0.0000,   0.0000,  -1.0000,   0.1502 }},
    {{-0.0000,  -1.0000,  -0.0000,   1.0790}},
    {{0 ,       0,        0,   1.0000    }} }}; //example for testing send

//packet to send
struct data{
    bool shot;
    Matrix4x4 position;
};

struct data primo = {true, T1};

//socket TCP



int main()
{
try{
    TCPSocket sock(servAddress, SOCKET_SERVER_PORT);   
    sock.send(&primo, sizeof(struct data));
}catch(SocketException &e){
    cerr << e.what() << endl;
    system("PAUSE");
}

cout<<endl<<"Matrix and bool sendend server"<<endl;
return 0;
}

“发送”到服务器正常(来自此客户端,没有错误),但服务器在接收时出错。我注意到 recv() 函数需要一个字符缓冲区......所以,这个错误是由于这个......

有人可以给我一个代码示例,帮助我正确发送和接收这个结构,而不会丢失从客户端到服务器的数据?

两台 PC 的架构相同(Windows 7 64 位,英特尔处理器,相同的 RAM 和硬件..)

提前谢谢...

【问题讨论】:

  • 也许这会有所帮助? codeproject.com/Articles/13071/…
  • 不要使用structs 作为网络协议。使用网络协议作为网络协议。通过使用struct,您在机器之间引入了六个依赖项。用八位字节定义一个应用程序协议,并为自己编写一个库来发送和接收它。或使用现有协议。
  • 我已经更新了我的问题,如果你能帮助我的话。
  • 您在未阅读 cmets 的情况下更新了您的问题。使用struct 作为网络协议是个坏主意。您引入了对处理器架构、处理器模式、编译器、编译器版本、编译 struct 时生效的编译器选项、周围的#pragmas 的依赖关系,...不要这样做。

标签: c++ sockets tcp struct


【解决方案1】:

通过网络发送数据时存在几个问题。

  1. 根据最简单的情况假设,当发送方和接收方使用相同的编译器版本构建并且都运行在具有相同(或非常接近)架构(操作系统、CPU、32/64 等)的机器上时,您可以使用 C结构“原样”。
  2. 对于最复杂的情​​况,当您对接收方一无所知(不同的操作系统、不同的编程语言等)时,您应该使用一种序列化方法:数据层的 XML 表示、协议层的 HTTP 和传输的 TCP。
  3. 当然,您可以使用库、各种 RPC 实现等。 假设您有 p.1(最简单的情况),您应该执行以下操作:
  4. 设置编译器以使用 1 字节对齐方式打包结构。
  5. 在结构中包含守卫:页眉、页脚和长度: 结构数据 { 字符头; // 将此设置为一些非常具体的值,例如 0x02 int64 长度; // 放 sizeof(data) 布尔射击; Matrix4x4位置; 字符页脚; // 将此设置为一些非常具体的值,例如 0x03 };
  6. 开发接收程序等待header(传输从0x02开始),然后接收length(它的大小是定义好的sizeof(int64)),然后读取length字节并检查footer(传输从0x03停止)
  7. 祝你好运

【讨论】:

  • 我已经更新了我的问题,现在更清楚了...如果你可以 Sergey,请告诉我该怎么做...
【解决方案2】:

一个 TCP 连接一个字节流。因此,首先要根据将发送和接收的字节来记录您的协议。然后实现代码以精确地发送和接收您指定的字节。然后,您可以通过以下技术进行故障排除:

  1. 发送方是否准确发送协议指定的字节?如果没有,请停止,发件人已损坏。

  2. 接收方是否正确处理协议指定的字节?如果没有,停止,接收器坏了。

  3. 协议已损坏,因为发送方和接收方都遵循它,并且整个系统仍然无法正常工作。 (这种情况经常发生。要获得正确的协议需要大量经验。)

如果您不在字节级别记录协议,则几乎不可能进行故障排除。所以,请不要跳过这一步。

【讨论】:

  • 谢谢大卫...我是套接字的初学者...在此尝试之前从来没有做过...所以,我不是协议方面的老手...感谢您的想法。 .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 2016-05-09
  • 1970-01-01
  • 2012-11-18
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多