C# - 服务器和Java的客户端:TCP套接字通信问题 [英] C#-Server and Java-Client: TCP Socket Communication Issues

查看:134
本文介绍了C# - 服务器和Java的客户端:TCP套接字通信问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中使用写了一个服务器程序 TCPListner 并使用套接字的客户端程序在Java中,但我无法从Java客户端的复杂对象发送到C#服务器。



当我用字符串转换成字节数组,
,它总是显示在消息的开始部分无效字符发送从Java客户端C#服务器一个简单的字符串转换时返回字符串(使用 Encoding.utf8.getstring(bytesArray))在C#中的服务器。当我通过从C#到Java客户端的字符串,显示无效头错误。



请帮助我,如果任何一个有任何替代或不知道紧靠它可以解决任何免费的API我问题。我曾尝试 Java的CS-桥发送复杂的对象,但它始终显示C#服务器上的异常。



下面是代码:



C#服务器代码 - 主要功能

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Net
;使用的System.Net.Sockets
;
:使用System.IO;

命名空间netSocketServer
{
类节目
{
静态无效的主要(字串[] args)
{
的TcpListener服务器=新的TcpListener(IPAddress.Any,8888);

VAR IP = Dns.GetHostEntry(Dns.GetHostName())AddressList.Where(IP = GT; ip.AddressFamily == AddressFamily.InterNetwork)。选择(IP = GT; IP).FirstOrDefault ();

server.Start();
Console.WriteLine(+ IP.ToString()服务器在运行);


TcpClient的ClientSocket的= server.AcceptTcpClient();
Console.WriteLine(客户端连接...);

作家WR =新编剧(ClientSocket的);
wr.start();

读卡器R =新的阅读器(ClientSocket的);
r.start();

Console.Read();
}
}
}



C#服务器读取器类

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用的System.Threading;使用的System.Net.Sockets
;使用System.Net
;
:使用System.IO;


命名空间netSocketServer
{
类Reader中的
{
TcpClient的插座;
的NetworkStream纳秒;

公共读卡器(TcpClient的S)
{
座= S;
NS = socket.GetStream();
}
公共无效的start()
{
新的Thread(
T => {
,而(真)
{
尝试
{
INT大小= ns.ReadByte();
字节[] = BUFF新的字节[大小];

ns.Read(BUFF,0 ,大小);

字符串消息= Encoding.UTF8.getString(BUFF);

Console.WriteLine(来自客户端的消息:{0},邮件);

ns.Flush();
}
赶上(例外五)
{
Console.WriteLine(客户端断开连接:+ e.Message) ;
}
}
})启动();
}

}
}



C#服务器作家班

 使用系统; 
使用System.Collections.Generic;
:使用System.IO;
使用System.Linq的;使用的System.Net.Sockets
;
使用System.Text;
使用的System.Threading;

命名空间netSocketServer
{
类作家
{
TcpClient的插座;
的NetworkStream纳秒;

公共作家(TcpClient的S)
{
座= S;
NS = socket.GetStream();
}
公共无效的start()
{
新的Thread(
T => {
,而(真)
{
尝试
{
Console.Write(请输入您的留言:);
字符串消息=到Console.ReadLine();
字节[] = BUFF Encoding.UTF8。 GetBytes会(消息);
字节大小=(字节)Message.Length;
ns.WriteByte(大小);
ns.Write(BUFF,0,buff.Length);
ns.Flush();
}
赶上(IOException异常E)
{
Console.WriteLine(客户端断开连接:+ e.Message);
座.Close();
Thread.CurrentThread.Abort();
Console.WriteLine(按任意键Closse服务器......);
}
}
})启动();
}

}
}



Java客户端 - 主要功能

 包javaclient.net; 

进口java.io.IOException异常;
进口的java.net.Socket;
进口java.util.Scanner中;
/ **
*
* @author努曼
* /
公共类JavaClientNet {

/ **
* @param ARGS命令行参数
* /
公共静态无效的主要(字串[] args)
{
Socket套接字;
读取R;
作家WR;

扫描器S =新的扫描仪(System.in);


{
// TODO代码应用程序逻辑在这里

System.out.print(请输入服务器IP:);
插座=新的Socket(s.next(),8888);

WR =新编剧(插座);
wr.start();

R =新的读(插座);
r.start();
}
赶上(IOException异常前)
{
的System.out.println(ex.getMessage());
}
}
}



Java客户端 - 读者级

 包javaclient.net; 

进口java.io.IOException异常;
进口java.io.ObjectInputStream中;
进口的java.net.Socket;

/ **
*
* @author努曼
* /
公共类阅读继承Thread
{
Socket套接字;
ObjectInputStream的inStream中;

读取(插座S)
{
座= S;
尝试{
inStream中=新的ObjectInputStream(socket.getInputStream());
}
赶上(IOException异常前)
{
的System.out.println(ex.getMessage());
}
}
@覆盖
公共无效的run()
{
,而(真)
{

{
字符串str;
字节大小= inStream.readByte();
的byte [] buf中=新的字节[大小]
inStream.read(BUF);
海峡=新的String(BUF);
的System.out.println(消息的形式服务器:+ STR);
}
赶上(IOException异常E)
{
的System.out.println(e.getMessage());
Thread.currentThread()停止()。
}
}
}
}



Java的客户端 - 作家班

 包javaclient.net; 

进口java.io.IOException异常;
进口java.io.ObjectOutputStream中;
进口的java.net.Socket;
进口java.util.Scanner中;
进口javacsconverter.core.tobyte.ToByteConvertHelper;

/ **
*
* @author努曼
* /
公共类作家继承Thread
{
Socket套接字;
的ObjectOutputStream outStream;
扫描仪扫描=新的扫描仪(System.in);


作家(插座S)
{
座= S;

{
outStream =新的ObjectOutputStream(socket.getOutputStream());
}
赶上(IOException异常前)
{
的System.out.println(ex.getMessage());
}
}
@覆盖
公共无效的run()
{
,而(真)
{

{

System.out.print(请输入您的留言:);


字符串str = scanner.nextLine();

字节[] = BUFF str.getBytes();

outStream.write(BUFF);

outStream.flush();
}
赶上(IOException异常前)
{
的System.out.println(ex.getMessage());
}

}
}
}


解决方案

的一般注意事项



请不要中止线程(包括C#和Java)。



C#服务器



Program类



有一个数据的比赛,因为静态控制台类由多个线程:




  1. 主线程:在 Program.Main()方法调用 Console.Read()方法;

  2. 工人螺纹:在 Writer.start()方法调用到Console.ReadLine()



请考虑更换计划的 Console.Read()方法调用。主要()方法不同的东西,例如, Thread.sleep代码(Timeout.Infinite)



Reader类



有是一个错误 - 在 Stream.Read()方法不保证在一次读取指定大小的阵列(一个呼叫),则返回值应该被用于确定读取的实际字节数。让我们来看看原始的实现:

  INT大小= ns.ReadByte(); 
字节[] = BUFF新的字节[大小]

//的Stream.Read()方法不能保证读**整个阵列**毕其功于一役。
//请使用方法的返回值。
ns.Read(BUFF,0,大小);

字符串消息= Encoding.UTF8.GetString(BUFF);



修正版本:

  ///<总结> 
/// Helper方法读取指定的字节数组(字节数读的是数组的大小)。
///< /总结>
///&下; PARAM NAME =InputStream的方式>的输入流与所述; /参数>
///&下; PARAM NAME =缓冲>在输出缓冲器下; /参数>
私有静态无效的readFully(流的InputStream,字节[]缓冲区)
{
如果(InputStream的== NULL)
{
抛出新的ArgumentNullException(InputStream的) ;
}

如果(缓冲== NULL)
{
抛出新的ArgumentNullException(缓冲区);
}

INT totalBytesRead = 0;
INT bytesLeft = buffer.Length;
如果(bytesLeft< = 0)
{
抛出新的ArgumentException(没有什么指定的缓冲区中读取,缓冲区);
}

,而(totalBytesRead< buffer.Length)
{
变种读取动作= inputStream.Read(缓冲,totalBytesRead,bytesLeft);
如果(读取动作大于0)
{
totalBytesRead + =读取动作;
bytesLeft - =读取动作;
}
,否则
{
抛出新的InvalidOperationException异常(输入流到达终点读取所有字节之前);
}
}
}

公共无效的start()
{
...
INT大小= ns.ReadByte ();
字节[] = BUFF新的字节[大小]
的readFully(NS,浅黄色);使用
(VAR的MemoryStream =新的MemoryStream(BUFF,FALSE))
{
// StreamReader类用于提取被编码的字节顺序标记的UTF-8字符串(BOM )。
使用(VAR的StreamReader =新的StreamReader(MemoryStream的,Encoding.UTF8))
{
字符串消息= streamReader.ReadToEnd();
Console.WriteLine(来自客户端的消息:{0},邮件);
}
}

}



Writer类



首先,描述和确定字节的文本流的顺序考虑包括的字节顺序标记(BOM)每个消息(例如)。



此外,还有一个错误 - 错误的缓冲区长度值发送。让我们来看看原始的实现:

 字符串消息=到Console.ReadLine(); 
字节[] = BUFF Encoding.UTF8.GetBytes(消息);

//问题:代替字符串的长度,必须使用字节数组的大小
//因为UTF-8编码使用:通常,串长度=编码的字节数。
字节大小=(字节)Message.Length;
ns.WriteByte(大小);
ns.Write(BUFF,0,buff.Length);
ns.Flush();



修正版本:

  // UTF-8 BOM。 
变种编码=新的UTF8Encoding(真);

//缓冲区编码为UTF-8 BOM。
字节[] = BUFF encoding.GetPreamble()
.Concat(encoding.GetBytes(消息))
.ToArray();

//大小编码的缓冲区。
字节大小= Convert.ToByte(buff.Length);
ns.WriteByte(大小);
ns.Write(BUFF,0,buff.Length);
ns.Flush();



替代修正版本 - 的StreamWriter 类用于字符串作为UTF-8字节顺序标记(BOM)编码:

 字符串消息=到Console.ReadLine() ; 

使用(VAR的MemoryStream =新的MemoryStream())
{
使用(VAR的StreamWriter =新的StreamWriter(MemoryStream的,Encoding.UTF8,1024,真))
{
streamWriter.Write(消息);
}
memoryStream.Flush();

字节大小= Convert.ToByte(memoryStream.Length);
ns.WriteByte(大小);

memoryStream.Seek(0,SeekOrigin.Begin);
memoryStream.CopyTo(NS);
ns.Flush();
}



Java客户端



阅读类



首先,请考虑使用 DataInputStream以类,因为下面的语句根据问题是不正确的:




这是ObjectInputStream的反序列化的基本数据和对象以前使用ObjectOutputStream写入的。



- java.io.ObjectInputStream中的类,Java™平台
标准版。 7




流的实例是几乎相同的:



  = inStream中DataInputStream所新(socket.getInputStream()); 



二,有一个错误 - 读取的字节数组,而忽略返回值(实际数读取的字节):

 字符串str; 
字节大小= inStream.readByte();
的byte [] buf中=新的字节[大小]

//的InputStream.read()方法不能保证读**整个阵列**毕其功于一役。
//请使用方法的返回值。
inStream.read(BUF);
海峡=新的String(BUF);



三,如上所述,字节顺序标记(BOM)也包括在内。



修正版本:

  //注意:inStream中必须DataInputStream以类的一个实例。 
字节大小= inStream.readByte();

的byte [] buf中=新的字节[大小]
//的DataInputStream.readFully()方法读取完全填充缓冲区所需的字节数。
inStream.readFully(BUF);

//创建内存流的字节数组,读取UTF-8字符串。
试(ByteArrayInputStream进行的InputStream =新ByteArrayInputStream进行(BUF);
//的BOMInputStream类属于Apache的百科全书IO库
BOMInputStream bomInputStream =新BOMInputStream(的InputStream,FALSE)){
字符串的charsetName = bomInputStream.getBOMCharsetName();

//的IOUtils类属于Apache的百科全书IO库。
字符串消息= IOUtils.toString(bomInputStream,的charsetName);
的System.out.println(消息的形式服务器:+消息);
}



Writer类



有一个错误 - 没有明确指定编码。让我们来看看原始的实现:

 字符串str = scanner.nextLine(); 
字节[] = BUFF str.getBytes();



修正版本:

 字符串str = scanner.nextLine(); 
字节[] = byteOrderMarkBytes ByteOrderMark.UTF_8.getBytes();
字节[] = stringBytes str.getBytes(StandardCharsets.UTF_8);
//的ArrayUtils.addAll()方法属于阿帕奇共享郎库。
字节[] = BUFF ArrayUtils.addAll(byteOrderMarkBytes,stringBytes);
outStream.writeByte(buff.length);
outStream.write(BUFF);
outStream.flush();



替代修正版本 - ByteArrayOutputStream 类用来连接阵列:

 字符串str = scanner.nextLine(); 
ByteArrayOutputStream byteArrayOutputStream =新ByteArrayOutputStream();
字节[] = byteOrderMarkBytes ByteOrderMark.UTF_8.getBytes();
byteArrayOutputStream.write(byteOrderMarkBytes);
字节[] = stringBytes str.getBytes(StandardCharsets.UTF_8);
byteArrayOutputStream.write(stringBytes);
byteArrayOutputStream.flush();

字节[] = BUFF byteArrayOutputStream.toByteArray();
outStream.writeByte(buff.length);
outStream.write(BUFF);
outStream.flush();



希望这有助于!


I have wrote a server program in C# using TCPListner and a client program in Java using socket but I fail to send complex objects from Java client to C# server.

When I send a simple string from Java client to C# server by converting the string into byte array, it always show some invalid characters at the start of message when converted back to String (using Encoding.utf8.getstring(bytesArray) ) in C# server. When I pass a String from C# to Java Client it shows invalid Header error.

Please help me if any one have any alternative or know abut any free API which can solve my problem. I have tried Java-cs-bridge to send complex objects but it always show Exception on C# server.

Here is the code:

C# Server Code - Main Function

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace netSocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(IPAddress.Any, 8888);

            var IP = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip =>ip.AddressFamily == AddressFamily.InterNetwork).Select(ip =>ip).FirstOrDefault();

            server.Start();
            Console.WriteLine("Server is Running at " + IP.ToString());


            TcpClient clientSocket = server.AcceptTcpClient();
            Console.WriteLine("Client Connected ... ");

            Writer wr = new Writer(clientSocket);
           wr.start(); 

            Reader r = new Reader(clientSocket);
            r.start();

            Console.Read();
        }
    }
}

C# Server Reader Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;


namespace netSocketServer
{
    class Reader
    {
        TcpClient socket;
        NetworkStream ns;

        public Reader(TcpClient s)
        {
            socket = s;
            ns = socket.GetStream() ;
        }
        public void start() 
        {
            new Thread(
                t => {
                    while (true)
                    {
                        try
                        {
                            int size = ns.ReadByte();
                            byte[] buff = new byte[size];

                            ns.Read(buff,0,size);

                            String message = Encoding.UTF8.getString(buff);

                            Console.WriteLine("Message from Client : {0}",message);

                            ns.Flush();
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Client Disconnected : " + e.Message);
                        }
                    }
                }).Start();
        } 

    }
}

C# Server Writer Class

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace netSocketServer
{
    class Writer
    {
        TcpClient socket;
        NetworkStream ns;

        public Writer(TcpClient s)
        {
            socket = s;
            ns = socket.GetStream();
        }
        public void start() 
        {
            new Thread(
                t => {
                    while (true)
                    {
                        try
                        {
                            Console.Write("Please Enter your Message : ");
                            string Message = Console.ReadLine();
                            byte[] buff = Encoding.UTF8.GetBytes(Message);
                            byte size = (byte)Message.Length;
                            ns.WriteByte(size);
                            ns.Write(buff, 0, buff.Length);
                            ns.Flush();
                        }
                        catch(IOException e)
                        {
                            Console.WriteLine("Client Disconnected : " + e.Message);
                            socket.Close();
                            Thread.CurrentThread.Abort();
                            Console.WriteLine("Press any key to Closse Server .... ");
                        }
                    }
                }).Start();
        } 

    }
}

Java Client - Main Function

package javaclient.net;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
 *
 * @author Numan
 */
public class JavaClientNet {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) 
    {
        Socket socket;
        Read r;
        Writer wr;

        Scanner s = new Scanner(System.in);

        try 
        {
            // TODO code application logic here

            System.out.print("Please Enter Server IP : ");
            socket = new Socket(s.next(), 8888);

            wr = new Writer(socket);
            wr.start();

            r = new Read(socket);
            r.start();
        }
        catch (IOException ex) 
        {
            System.out.println(ex.getMessage());   
        }
    }
}

Java Client - Reader Class

package javaclient.net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;

/**
 *
 * @author Numan
 */
public class Read extends Thread
{
    Socket socket;
    ObjectInputStream inStream;

    Read(Socket s)
    {
        socket = s;
        try {
            inStream = new ObjectInputStream(socket.getInputStream());
            }
        catch (IOException ex) 
        {
            System.out.println(ex.getMessage());
        }
    }
    @Override
    public void run()
    {
     while(true)
     {
         try
         {
            String str;
            byte size = inStream.readByte();
            byte[] buf = new byte[size];
            inStream.read(buf);
            str = new String(buf);
            System.out.println("Message form Server : "+str);
         }
         catch(IOException e)
         {
             System.out.println(e.getMessage());
             Thread.currentThread().stop();
         } 
     }   
    }
}

Java Client - Writer Class

package javaclient.net;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import javacsconverter.core.tobyte.ToByteConvertHelper;

/**
 *
 * @author Numan
 */
public class Writer extends Thread
{
    Socket socket;
    ObjectOutputStream outStream;
    Scanner scanner = new Scanner(System.in);


    Writer(Socket s)
    {
        socket =s;
        try 
        {
            outStream = new ObjectOutputStream(socket.getOutputStream());
        }
        catch (IOException ex) 
        {
            System.out.println(ex.getMessage());
        }
    }
    @Override
    public void run()
    {
        while(true)
        {
            try 
            {

                System.out.print("Please Enter Your Message : ");


                String str = scanner.nextLine();

                byte[] buff = str.getBytes();

                outStream.write(buff);

                outStream.flush();
            } 
            catch (IOException ex) 
            {
                System.out.println(ex.getMessage());
            }

        }
    }
}

解决方案

General notes

Please do not abort the threads (both C# and Java).

C# Server

Program class

There is a data race because the static Console class is used by multiple threads:

  1. Main thread: the Program.Main() method calls the Console.Read() method;
  2. Worker thread: the Writer.start() method calls the Console.ReadLine() method.

Please consider replacing the Console.Read() method call of the Program.Main() method with something different, for example, Thread.Sleep(Timeout.Infinite).

Reader class

There is a mistake — the Stream.Read() method is not guaranteed to read the array of the specified "size" at once (one call), the return value should be used to determine the actual number of bytes read. Let's see the original implementation:

int size = ns.ReadByte();
byte[] buff = new byte[size];

// The Stream.Read() method does not guarantee to read the **whole array** "at once".
// Please use the return value of the method.
ns.Read(buff, 0, size);

String message = Encoding.UTF8.GetString(buff);

Corrected version:

/// <summary>
/// Helper method to read the specified byte array (number of bytes to read is the size of the array).
/// </summary>
/// <param name="inputStream">Input stream.</param>
/// <param name="buffer">The output buffer.</param>
private static void ReadFully(Stream inputStream, byte[] buffer)
{
    if (inputStream == null)
    {
        throw new ArgumentNullException("inputStream");
    }

    if (buffer == null)
    {
        throw new ArgumentNullException("buffer");
    }

    int totalBytesRead = 0;
    int bytesLeft = buffer.Length;
    if (bytesLeft <= 0)
    {
        throw new ArgumentException("There is nothing to read for the specified buffer", "buffer");
    }

    while (totalBytesRead < buffer.Length)
    {
        var bytesRead = inputStream.Read(buffer, totalBytesRead, bytesLeft);
        if (bytesRead > 0)
        {
            totalBytesRead += bytesRead;
            bytesLeft -= bytesRead;
        }
        else
        {
            throw new InvalidOperationException("Input stream reaches the end before reading all the bytes");
        }
    }
}

public void start()
{
    ...
    int size = ns.ReadByte();
    byte[] buff = new byte[size];
    ReadFully(ns, buff);
    using (var memoryStream = new MemoryStream(buff, false))
    {
        // The StreamReader class is used to extract the UTF-8 string which is encoded with the byte order mark (BOM).
        using (var streamReader = new StreamReader(memoryStream, Encoding.UTF8))
        {
            string message = streamReader.ReadToEnd();
            Console.WriteLine("Message from Client: {0}", message);
        }
    }
    ...
}

Writer class

First of all, to describe and determine byte the order of the text stream consider including the byte order mark (BOM) for each message (for example).

Also, there is a mistake — wrong "buffer length" value is sent. Let's see the original implementation:

string Message = Console.ReadLine();
byte[] buff = Encoding.UTF8.GetBytes(Message);

// Problem: instead of the length of the string, the size of byte array must be used
// because the UTF-8 encoding is used: generally, string length != "encoded number of bytes".
byte size = (byte)Message.Length;
ns.WriteByte(size);
ns.Write(buff, 0, buff.Length);
ns.Flush();

Corrected version:

// UTF-8 with BOM.
var encoding = new UTF8Encoding(true);

// Buffer encoded as UTF-8 with BOM.
byte[] buff = encoding.GetPreamble()
    .Concat(encoding.GetBytes(message))
    .ToArray();

// Size of the encoded buffer.
byte size = Convert.ToByte(buff.Length);
ns.WriteByte(size);
ns.Write(buff, 0, buff.Length);
ns.Flush();

Alternative corrected version — the StreamWriter class is used to encode the string as UTF-8 with the byte order mark (BOM):

string message = Console.ReadLine();

using (var memoryStream = new MemoryStream())
{
    using (var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8, 1024, true))
    {
        streamWriter.Write(message);
    }
    memoryStream.Flush();

    byte size = Convert.ToByte(memoryStream.Length);
    ns.WriteByte(size);

    memoryStream.Seek(0, SeekOrigin.Begin);
    memoryStream.CopyTo(ns);
    ns.Flush();
}

Java Client

Read class

First, please consider using DataInputStream class because the following statement is not true according to the question:

An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

-- java.io.ObjectInputStream class, Java™ Platform Standard Ed. 7.

The instantiation of the stream is almost the same:

inStream = new DataInputStream(socket.getInputStream());

Second, there is a mistake — reading the byte array, but ignoring the return value (actual number of bytes read):

String str;
byte size = inStream.readByte();
byte[] buf = new byte[size];

// The InputStream.read() method does not guarantee to read the **whole array** "at once".
// Please use the return value of the method.
inStream.read(buf);
str = new String(buf);

Third, as stated above, the byte order mark (BOM) is included.

Corrected version:

// Note: inStream must be an instance of DataInputStream class.
byte size = inStream.readByte();

byte[] buf = new byte[size];
// The DataInputStream.readFully() method reads the number of bytes required to fill the buffer entirely.
inStream.readFully(buf);

// Create in-memory stream for the byte array and read the UTF-8 string.
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
    // The BOMInputStream class belongs to Apache Commons IO library.
    BOMInputStream bomInputStream = new BOMInputStream(inputStream, false)) {
    String charsetName = bomInputStream.getBOMCharsetName();

    // The IOUtils class belongs to Apache Commons IO library.
    String message = IOUtils.toString(bomInputStream, charsetName);
    System.out.println("Message form Server : " + message);
}

Writer class

There is a mistake — the encoding is not specified explicitly. Let's see the original implementation:

String str = scanner.nextLine();
byte[] buff = str.getBytes();

Corrected version:

String str = scanner.nextLine();
byte[] byteOrderMarkBytes = ByteOrderMark.UTF_8.getBytes();
byte[] stringBytes = str.getBytes(StandardCharsets.UTF_8);
// The ArrayUtils.addAll() method belongs to Apache Commons Lang library.
byte[] buff = ArrayUtils.addAll(byteOrderMarkBytes, stringBytes);
outStream.writeByte(buff.length);
outStream.write(buff);
outStream.flush();

Alternative corrected version — the ByteArrayOutputStream class is used to concatenate the arrays:

String str = scanner.nextLine();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] byteOrderMarkBytes = ByteOrderMark.UTF_8.getBytes();
byteArrayOutputStream.write(byteOrderMarkBytes);
byte[] stringBytes = str.getBytes(StandardCharsets.UTF_8);
byteArrayOutputStream.write(stringBytes);
byteArrayOutputStream.flush();

byte[] buff = byteArrayOutputStream.toByteArray();
outStream.writeByte(buff.length);
outStream.write(buff);
outStream.flush();

Hope this helps!

这篇关于C# - 服务器和Java的客户端:TCP套接字通信问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆