簡體   English   中英

通過套接字將字符串作為字節數組從C#發送到Java

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM