0

首先,我对使用 sockect 和 TCP/IP 数据包进行网络非常陌生,如果您能以非常清晰的方式解释,我将不胜感激。我的机器人程序第一次尝试将 kinect 与我们当前的机器人一起使用,但我们遇到了问题。目前他们用 java 编码,而他们计划用 C++ 编码 kinect。是否可以使用 TCP/IP 数据包在两种语言之间发送信息?我们需要一个 C++ 客户端和一个 Java 服务器。如果有人有链接或示例,我将不胜感激,谢谢!

4

3 回答 3

1

Java 和 C/C++ 之间通信的真正问题是字节顺序问题。如果要发送二进制数据,则必须清楚完整地设计通信结构,包括数字大小(以字节为单位)、位顺序(lsb/msb、交换字节或简而言之非交换字节、整数和longs)和结构打包(结构中字段之间的填充字节数)。

如果可以避免,我建议您不要使用二进制进行通信。有两个原因;

  1. 无需担心位顺序、字节交换和结构打包。
  2. 在不解码数据的情况下窃听通信。你在这里仍然有 ascii/unicode 问题。

编辑 在 C/C++ 中,数据的存储方式使 CPU 访问变得快速而轻松。类/结构的字段在字边界上对齐(因为大多数 CPU 只能以完整的字块访问内存),并且位的顺序与 CPU 匹配。但是,CPU 可以有不同的位顺序和字长(16、32、64,...)。大多数英特尔 CPU 都是小端,而大多数其他设计都是大端。为了让生活更有趣,java 虚拟机在每个平台上都是大端的。http://en.wikipedia.org/wiki/Endianness

因此,如果您希望两台 C/C++ 机器能够通信,那么您必须以双方都可以读取的方式发送数据。通常,要在异构环境中进行通信(称为“有线”),您需要指定所有通信都以特定格式完成。TCP/IP 使用 MSB(最高有效位)排序。然后,所有程序都必须从有线格式转换(如有必要)。

因为 CPU 在字长块中消耗内存,所以编译器会将填充字节放在不填充整个机器字的字段之间。对于读取 32 位字的机器,结构如下:

struct example1 {
  char someFlag;
  int  someCount;
};

实际上会占用 8 个字节的内存。第一个字段由一个数据字节和 3 个填充字节组成,因此整数引用在字边界上对齐。如果一个幼稚的通信器尝试以这种结构发送数据,例如send(&example1, sizeof(example1));向另一个具有不同字长或字节顺序的系统发送数据,而另一个系统则这样做read(&example1, sizeof(example1));,那么 example1.someCount 的值可能与预期的非常不同。

在您将 Java 投入其中之前,大部分内容通常都是学术性的。因为Java总是MSB格式。因此,即使在相同的硬件上,从 C/C++ 应用程序发送到 Java 应用程序,也可能导致同样的意外结果。

Java 包含我最喜欢的 I/O 类,java.nio.ByteBuffer. 它能够从几乎任何来源读取整数、长整数、浮点数和双精度数。如果您知道数据是如何创建的,它将读取它。ByteBuffer 有getShort,getInt等方法来获取任何类型,以及order()设置数据字节顺序的方法。

于 2012-10-10T18:46:28.180 回答
1

每当您希望两个程序通过网络相互通信时,您需要定义一个协议

在 TCP 之上定义的协议需要指定一种方法来告诉接收者何时收到了整个消息。两种常见的方法是:

  • 指定一些特殊的数据序列来表示“结束”。一个例子是 HTTP,它使用一个特殊的 CRLF 字符来表示消息的非有效负载部分的结束。
  • 在消息的某些预定义部分中指定消息的长度。一个示例是 HTTP,它在“Content-Length”标头中指定有效负载的长度。

您可以在此处找到有关 HTTP 消息结构的更多信息:http: //www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

此外,您可能希望使用与平台无关的格式来编码有效负载。一个好的二进制格式是 Google 的协议缓冲区,它在 Java 和 C++ 中得到很好的支持:http ://code.google.com/p/protobuf/

于 2012-10-10T21:40:41.667 回答
0

当然,您可以在实现不同语言的程序之间交换信息。(您是否期望整个 Internet 都使用 Java?)

这是我在谷歌搜索“socket programming {Java, C++}”后发现的:

http://codebase.eu/tutorial/linux-socket-programming-c/ - 似乎没问题

http://www.javaworld.com/jw-12-1996/jw-12-sockets.html - Java 教程

但小心点。根据您的硬件架构,您在交换二进制数据(字节顺序等)时可能会遇到一些问题。当您使用面向对象的语言时,您可以考虑使用某种处理低级通信的中间件——例如Ice。但是,在您的情况下,这可能是矫枉过正。

于 2012-10-10T18:10:31.513 回答