简体   繁体   English

Java Socket客户端和C++(基于Boost)服务器之间的网络

[英]Networking between Java Socket client and C++ (Boost based) server

At work I'm designing a user interface for controlling groups of robots.在工作中,我正在设计一个用于控制机器人组的用户界面。 The robots use UDP broadcasts to manage their movements with one another.机器人使用 UDP 广播来管理彼此的动作。

The GUI needs to be able to communicate to the robots. GUI 需要能够与机器人通信。 To this end, an intermediary server is run.为此,运行中间服务器。 All robots listen to it (with UDP sensors), and all running GUIs connect to it (via TCP).所有机器人都听它(使用 UDP 传感器),所有运行的 GUI 都连接到它(通过 TCP)。 It manages GUI <-> Robot communications.它管理 GUI <-> 机器人通信。

However, the server is written with the C++ Boost library, and the GUI is written in Java, and some issues with the networking are occurring.但是,服务器是用 C++ Boost 库编写的,GUI 是用 Java 编写的,并且出现了一些网络问题。 I connect to the server with a socket fairly easily:我很容易用套接字连接到服务器:

try {
    socket = new Socket(targetAddress, targetPort);
} catch (IOException e) { e.printStackTrace(); }

The server registers the connection and everything looks good.服务器注册连接,一切看起来都很好。

However, when I try to send Strings:但是,当我尝试发送字符串时:

try {
    stream.writeUTF(message);
    stream.flush();
} catch (IOException e) { e.printStackTrace(); }

Note: I was initially using a PrintWriter to send strings one at a time (println()) but switched to DataOutputStream to see if it would help.注意:我最初使用 PrintWriter 一次发送一个字符串 (println()),但切换到 DataOutputStream 以查看它是否有帮助。

We run into problems.我们遇到了问题。 Boost does not even register that I sent the message, even though Java successfully did.即使 Java 成功地做到了,Boost 甚至都没有注册我发送的消息。 Additionally, when Strings are sent from the server, they are in an unrecognizable format.此外,当从服务器发送字符串时,它们的格式无法识别。

A bit of looking into the problem suggests that Boost automatically appends "header" text to all messages it sends, helping it to archive messages it receives.稍微研究一下这个问题表明,Boost 会自动将“标题”文本附加到它发送的所有消息中,帮助它归档收到的消息。 Since Java doesn't do this, it seems like this may be the cause.由于 Java 没有这样做,看来这可能是原因。 Is this correct?这个对吗? If so, how can we get around it?如果是这样,我们怎样才能绕过它?


A few notes:几点注意事项:

  • Due to time constraints, switching to different libraries/languages on a large scale is not really an option.由于时间限制,大规模切换到不同的库/语言并不是一个真正的选择。 However, if there is a C++ TCP library that will allow the server to receive the messages I send, and we can easily integrate it, that would be perfect .但是,如果有一个 C++ TCP 库可以让服务器接收我发送的消息,并且我们可以轻松集成它,那就完美了。
  • The Java networking code works perfectly when connecting to a Java server. Java 网络代码在连接到 Java 服务器时可以完美运行。 The difficulties seem to be happening in the Boost-Java interface.困难似乎发生在 Boost-Java 接口中。
  • Unfortunately, neither myself or the other person working on this aspect of the project are that experienced in networking.不幸的是,我本人或从事该项目这方面工作的其他人都没有网络经验。 :( My experience is with Java and GUI development, and the other person is an AI programmer / hardware specialist. Any and all help with this issue would be incredibly welcome. :( 我的经验是 Java 和 GUI 开发,另一个人是 AI 程序员/硬件专家。非常欢迎任何有关此问题的帮助。

Start with sending & receiving first bytes, then ints.从发送和接收第一个字节开始,然后是整数。 Be aware of sizing (fe 64 bit ints in C++) and byte ordering (least vs most significant first).请注意大小(C++ 中的 fe 64 位整数)和字节顺序(最小与最重要的优先)。 As Sam Miller mentioned, you will need to create your own protocol, that will define what kind of messages you can send & how their elements are ordered.正如 Sam Miller 所提到的,您将需要创建自己的协议,该协议将定义您可以发送什么样的消息以及它们的元素如何排序。

What probably happens is that Boost sends the length of the string first.可能发生的是 Boost 首先发送字符串的长度。 Do read up on the wire format of messages sent using the Boost library, and of the wire format used by DataOutputStream.请阅读使用 Boost 库发送的消息的有线格式以及 DataOutputStream 使用的有线格式。

First of all you need to know which encoding, byte order and package format Boost is using to determine the start and the end of a comand.首先,您需要知道 Boost 使用哪种编码、字节顺序和 package 格式来确定命令的开始和结束。 For example, a comand could be like WALK, but you simply will not send a WALK string over the connection.例如,命令可能类似于 WALK,但您根本不会通过连接发送 WALK 字符串。 It can be using a delimiter like \n so you would send: WALK\n another thing, is to know what the encoding is it using, you can use the string method myString.getBytes("UTF-8");它可以使用像 \n 这样的分隔符,所以你会发送: WALK\n 另一件事是知道它使用的是什么编码,你可以使用字符串方法 myString.getBytes("UTF-8"); to send the byte[] in UTF-8 over the network using socket´s outputstream.使用套接字的输出流通过网络发送 UTF-8 中的字节 []。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM