如何将 \x 字符串转换为二进制并通过套接字发送
how to convert \x string to binary and send via socket
我在Java
中有这种字符串
String java_str = "\x00\x00\x00@\x02\t\x01\x00\******
如您所见,其中混合了二进制和文本数据。
当我通过 python 通过套接字发送这个字符串时
示例代码
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
clientSocket.connect(("127.0.0.1", 11111));
clientSocket.send(bin_data.encode());
我正在接收这个二进制数据
如何使用 Java 套接字将数据发送到服务器以接收二进制数据而不是像这样的字符串
您问题中的字符串无效Java:
String java_str = "\x00\x00\x00@\x02\t\x01\x00\...";
因为 \x
不是有效的 Java 字符串转义。
您的实际 Java 代码(来自评论)显然是这样的:
Socket socket = new Socket("127.0.0.1", 9091);
OutputStream socketOutputStream = socket.getOutputStream();
String s = "\x00\x00\x00@\x02\t\x01\x00\x00\x00\x00...";
socketOutputStream.write(s.getBytes("ASCII"));
你实际上做的是转义反斜杠。所以字符串文字实际上包含文字反斜杠、x
字符等。 (这就是您在数据包转储中看到的内容。)
在 Java 字符串文字中表达任意 Unicode 代码点(例如 NUL
或 U+0000
代码点)的方法是使用 Java 的 Unicode转义语法;例如\u0000
.
String s = "\u0000\u0000\u0000@\u0002\t\u0001\u0000\u0000...";
见\x Escape in Java?
在这种情况下,更好的选择是将数据表示为字节数组;例如
byte[] bytes = { 0, 0, 0, '@', 2, '\t', 1, 0, ...};
用二进制表示更易读,概念上更清晰
数据为二进制而不是将其编码为文本并进行转换
到二进制。
(但请注意,您需要对 0x80
和 0xff
之间的任何代码以及数组初始值设定项中的任何非常量表达式使用 (byte)
类型转换。那是因为Java byte
类型已签名 ...)
如果您的 Java 字符串包含显式 (C / C++ ?) \xnn
序列,您可以使用一些自定义代码将其转换为常规字符串。这有点乏味,但编码相当简单......如果你以前手写过词法分析器。
请注意,常用的 Apache Commons StringEscapeUtils
(javadoc) class 在这里不起作用。 StringEscapeUtils
实现(严格)Java 字符串文字语法的转义,并且 Java 不识别字符串中的 \xnn
转义。 (StringEscapeUtils
甚至不处理 \u
... 这在技术上是正确的,尽管出乎意料。)
我在Java
中有这种字符串String java_str = "\x00\x00\x00@\x02\t\x01\x00\******
如您所见,其中混合了二进制和文本数据。 当我通过 python 通过套接字发送这个字符串时 示例代码
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
clientSocket.connect(("127.0.0.1", 11111));
clientSocket.send(bin_data.encode());
我正在接收这个二进制数据
如何使用 Java 套接字将数据发送到服务器以接收二进制数据而不是像这样的字符串
您问题中的字符串无效Java:
String java_str = "\x00\x00\x00@\x02\t\x01\x00\...";
因为 \x
不是有效的 Java 字符串转义。
您的实际 Java 代码(来自评论)显然是这样的:
Socket socket = new Socket("127.0.0.1", 9091);
OutputStream socketOutputStream = socket.getOutputStream();
String s = "\x00\x00\x00@\x02\t\x01\x00\x00\x00\x00...";
socketOutputStream.write(s.getBytes("ASCII"));
你实际上做的是转义反斜杠。所以字符串文字实际上包含文字反斜杠、x
字符等。 (这就是您在数据包转储中看到的内容。)
在 Java 字符串文字中表达任意 Unicode 代码点(例如 NUL
或 U+0000
代码点)的方法是使用 Java 的 Unicode转义语法;例如\u0000
.
String s = "\u0000\u0000\u0000@\u0002\t\u0001\u0000\u0000...";
见\x Escape in Java?
在这种情况下,更好的选择是将数据表示为字节数组;例如
byte[] bytes = { 0, 0, 0, '@', 2, '\t', 1, 0, ...};
用二进制表示更易读,概念上更清晰 数据为二进制而不是将其编码为文本并进行转换 到二进制。
(但请注意,您需要对 0x80
和 0xff
之间的任何代码以及数组初始值设定项中的任何非常量表达式使用 (byte)
类型转换。那是因为Java byte
类型已签名 ...)
如果您的 Java 字符串包含显式 (C / C++ ?) \xnn
序列,您可以使用一些自定义代码将其转换为常规字符串。这有点乏味,但编码相当简单......如果你以前手写过词法分析器。
请注意,常用的 Apache Commons StringEscapeUtils
(javadoc) class 在这里不起作用。 StringEscapeUtils
实现(严格)Java 字符串文字语法的转义,并且 Java 不识别字符串中的 \xnn
转义。 (StringEscapeUtils
甚至不处理 \u
... 这在技术上是正确的,尽管出乎意料。)