![](/img/trans.png)
[英]HBase java error - Expected HEADER=HBas but received HEADER=\x00\x00\x01\x0B
[英]Java send nullbyte (\x00) as 1 character using AsynchronousSocketChannel
我需要將 nullbyte 作為 1 個字符發送,此代碼將其作為 4 個字符發送,因此不是 nullbyte (\\x00) ,它不能作為純文本發送。 它正在發送到 Flash 客戶端。 我正在使用 AsynchronousSocketChannel 發送數據包。 nullbyte 是告訴服務器數據包已經結束。 例如,當我發送 test\\x00 時,它將它作為 test\\x00 發送,這是錯誤的。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws Exception {
String connect = "gfdg";
System.out.println(connect);
String request = connect;
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
SocketAddress serverAddr = new InetSocketAddress("artix.aqw.aq.com", 5588);
Future<Void> result = channel.connect(serverAddr);
result.get();
Attachment attach = new Attachment();
attach.channel = channel;
attach.buffer = ByteBuffer.allocate(2048);
attach.isRead = false;
attach.mainThread = Thread.currentThread();
Charset cs = Charset.forName("UTF-8");
String msg = request;
byte[] data = msg.getBytes(cs);
attach.buffer.put(data);
attach.buffer.flip();
ReadWriteHandler readWriteHandler = new ReadWriteHandler();
channel.write(attach.buffer, attach, readWriteHandler);
attach.mainThread.join();
}
}
class Attachment {
AsynchronousSocketChannel channel;
ByteBuffer buffer;
Thread mainThread;
boolean isRead;
}
class ReadWriteHandler implements CompletionHandler<Integer, Attachment> {
@Override
public void completed(Integer result, Attachment attach) {
if (attach.isRead) {
attach.buffer.flip();
Charset cs = Charset.forName("UTF-8");
int limits = attach.buffer.limit();
byte bytes[] = new byte[limits];
attach.buffer.get(bytes, 0, limits);
String msg = new String(bytes, cs);
String str = new String(bytes,cs).split("\0")[0];
System.out.format("Server Responded: " + str + "\n");
try {
msg = this.getTextFromUser();
} catch (Exception e) {
e.printStackTrace();
}
if (msg.equalsIgnoreCase("bye")) {
attach.mainThread.interrupt();
return;
}
attach.buffer.clear();
byte[] data = msg.getBytes(cs);
attach.buffer.put(data);
attach.buffer.flip();
attach.isRead = false; // It is a write
attach.channel.write(attach.buffer, attach, this);
} else {
attach.isRead = true;
attach.buffer.clear();
attach.channel.read(attach.buffer, attach, this);
}
}
@Override
public void failed(Throwable e, Attachment attach) {
e.printStackTrace();
}
private String getTextFromUser() throws Exception {
System.out.println("Please enter a message:");
BufferedReader consoleReader = new BufferedReader(
new InputStreamReader(System.in));
String msg = consoleReader.readLine() + "\\x00";
return msg;
}
}
在將字符串寫入通道后,您應該寫入一個空字節 ( 0x00
)。 您所做的不是它:您要附加字符串\\x00
(反斜杠后跟一個 x 和兩個 0)。
與我的第一直覺相反,如果您將 unicode 字符\
附加到您的字符串中,它似乎會起作用,但最佳方法是在放入字符串后將值為0
的byte
放入ByteBuffer
。
需要明確的是,我希望在附加\
字節會加倍,因為 Java 將字符編碼為 UTF-16,因此為 2 個字節。 但是我們明確地將字符串編碼為 UTF-8 以將其作為字節獲取,因此空字符確實被編碼為單個空字節。
這是一個小演示,顯示了每個方法寫入通道的數據長度,然后它的值為字節:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Buffer {
public static void main(String[] args) throws IOException {
try (Scanner scan = new Scanner(System.in)) {
boolean done = false;
while(!done) {
System.out.println("Enter string to encode, 'bye' to exit:");
String s = scan.nextLine();
if ("bye".equals(s.toLowerCase())) {
done = true;
break;
}
System.out.println("withNullChar");
String withNullChar = s + '\u0000';
ByteBuffer buff = ByteBuffer.allocate(1024);
buff.put(withNullChar.getBytes(StandardCharsets.UTF_8));
System.out.println("Length: " + buff.position());
buff.flip();
byte[] result = readBack(buff);
printArray(result);
System.out.println("withNullCharFaulty");
String withNullCharFaulty = s + "\\x00";
buff = ByteBuffer.allocate(1024);
buff.put(withNullCharFaulty.getBytes(StandardCharsets.UTF_8));
System.out.println("Length: " + buff.position());
buff.flip();
result = readBack(buff);
printArray(result);
System.out.println("with null byte");
buff = ByteBuffer.allocate(1024);
buff.put(s.getBytes(StandardCharsets.UTF_8)).put((byte) 0);
System.out.println("Length: " + buff.position());
buff.flip();
result = readBack(buff);
printArray(result);
}
}
}
public static byte[] readBack(ByteBuffer buff) throws IOException {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
try (WritableByteChannel channel = Channels.newChannel(bos)) {
channel.write(buff);
return bos.toByteArray();
}
}
}
public static void printArray(byte[] arr) {
StringBuilder sb = new StringBuilder();
for (byte b : arr)
sb.append(String.format("%02X ", b));
System.out.println(sb);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.