[英]Sending string as byte array from C# to Java via socket
我正在嘗試以下方法:
C#客戶端:
string stringToSend = "Hello man";
BinaryWriter writer = new BinaryWriter(mClientSocket.GetStream(),Encoding.UTF8);
//write number of bytes:
byte[] headerBytes = BitConverter.GetBytes(stringToSend.Length);
mClientSocket.GetStream().Write(headerBytes, 0, headerBytes.Length);
//write text:
byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(stringToSend);
writer.Write(textBytes, 0, textBytes.Length);
Java服務器:
Charset utf8 = Charset.forName("UTF-8");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), utf8));
while (true) {
//we read header first
int headerSize = in.read();
int bytesRead = 0;
char[] input = new char[headerSize];
while (bytesRead < headerSize)
{
bytesRead += in.read(input, bytesRead, headerSize - bytesRead);
}
String resString = new String(input);
System.out.println(resString);
if (resString.equals("!$$$")) {
break;
}
}
字符串大小等於9,在兩邊都是正確的,但是,當我在Java端讀取字符串iteself時,數據看起來不正確。char緩沖區(``輸入''變量)的內容看起來像這樣:
“,“,“,'你好',''
我試圖通過反轉字節數組來更改字節序。還嘗試了在ASCII和UTF-8之間更改字符串編碼格式。其他類型的編寫器,以便將文本數據寫入流,但是為了學習起見,我嘗試使用原始字節數組。
乍看起來,您的索引有問題。
您的C#代碼正在發送一個轉換為4個字節的整數。
但是您的Java代碼只讀取一個字節作為字符串的長度。
從C#發送的接下來的3個字節將從字符串長度轉到三個零字節。
您的Java代碼正在讀取這3個零字節,並將它們轉換為空字符,這些空字符表示input []數組的前3個空字符。
C#客戶端:
string stringToSend = "Hello man";
BinaryWriter writer = new BinaryWriter(mClientSocket.GetStream(),Encoding.UTF8);
//write number of bytes: Original line was sending the entire string here. Optionally if you string is longer than 255 characters, you'll need to send another data type, perhaps an integer converted to 4 bytes.
byte[] textBytes = System.Text.Encoding.UTF8.GetBytes(stringToSend);
mClientSocket.GetStream().Write((byte)textBytes.Length);
//write text the entire buffer
writer.Write(textBytes, 0, textBytes.Length);
Java服務器:
Charset utf8 = Charset.forName("UTF-8");
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), utf8));
while (true) {
//we read header first
// original code was sending an integer as 4 bytes but was only reading a single char here.
int headerSize = in.read();// read a single byte from the input
int bytesRead = 0;
char[] input = new char[headerSize];
// no need foe a while statement here:
bytesRead = in.read(input, 0, headerSize);
// if you are going to use a while statement, then in each loop
// you should be processing the input but because it will get overwritten on the next read.
String resString = new String(input, utf8);
System.out.println(resString);
if (resString.equals("!$$$")) {
break;
}
}
這些
byte[] headerBytes = BitConverter.GetBytes(stringToSend.Length);
是4個字節。 而且它們不是字符數據,因此使用BufferedReader
讀取它們是沒有意義的。 只需直接讀取字節。
byte[] headerBytes = new byte[4];
// shortcut, make sure 4 bytes were actually read
in.read(headerBytes);
現在提取文本的長度並為其分配足夠的空間
int length = ByteBuffer.wrap(headerBytes).getInt();
byte[] textBytes = new byte[length];
然后閱讀文字
int remaining = length;
int offset = 0;
while (remaining > 0) {
int count = in.read(textBytes, offset, remaining);
if (-1 == count) {
// deal with it
break;
}
remaining -= count;
offset += count;
}
現在將其解碼為UTF-8
String text = new String(textBytes, StandardCharsets.UTF_8);
到此為止。
字節序必須與前4個字節匹配。 確保這一點的一種方法是使用“網絡順序”(big-endian)。 所以:
C#客戶端
byte[] headerBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(stringToSend.Length));
Java服務器
int length = ByteBuffer.wrap(headerBytes).order(ByteOrder.BIG_ENDIAN).getInt();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.