Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何通过Tcp将二进制流从Java发送到C#?_Java_C#_Tcpclient_Tcplistener - Fatal编程技术网

如何通过Tcp将二进制流从Java发送到C#?

如何通过Tcp将二进制流从Java发送到C#?,java,c#,tcpclient,tcplistener,Java,C#,Tcpclient,Tcplistener,我有一本书。我需要将Java客户机连接到它,并使它进行交互 以下是客户端C#代码: 这段代码的Java等价物是什么 我写了以下内容: InetAddress ip = InetAddress.getByName("localhost"); int PORT_NO = 2000; Socket socket = new Socket(ip, PORT_NO); // obtaining input and out streams DataInpu

我有一本书。我需要将Java客户机连接到它,并使它进行交互

以下是客户端C#代码:

这段代码的Java等价物是什么

我写了以下内容:

    InetAddress ip = InetAddress.getByName("localhost"); 

    int PORT_NO = 2000; 
    Socket socket = new Socket(ip, PORT_NO); 

    // obtaining input and out streams 
    DataInputStream reader = new DataInputStream(socket.getInputStream()); 
    DataOutputStream writer = new DataOutputStream(socket.getOutputStream());

    writer.writeChars("Hello");
    String str = reader.readUTF();
byte[] bytes = Encoding.UTF8.GetBytes(str);
writer.Write(bytes.Length);
writer.Write(bytes);  

int len = reader.ReadInt32();
byte[] bytes = reader.ReadBytes(len);
string str = Encoding.UTF8.GetString(bytes);
但是,我的java代码不起作用

服务器运行正常。服务器似乎没有收到Java客户端发送的字符串

我怎样才能做我需要的

编辑:根据@van dench的建议,我在C#server中使用了以下代码。现在,即使是C#客户也停止了工作

            byte[] strBytes = Encoding.UTF8.GetBytes(str);
            byte[] lenBytes = BitConverter.GetBytes(strBytes.Length);
            Array.Reverse(lenBytes);
            writer.Write(lenBytes);
            writer.Write(strBytes);
            writer.Flush(); 

            byte[] lenBytes = reader.ReadBytes(4);
            Array.Reverse(lenBytes);
            int len = BitConverter.ToInt32(lenBytes, 0);
            byte[] bytes = reader.ReadBytes(len);
            string str = Encoding.UTF8.GetString(bytes);

问题是,您在c代码中使用了ReadString和Write方法。它们使用一种Java不知道的长度前缀格式

带前缀的长度表示此方法在使用BinaryWriter实例的当前编码进行编码时,首先将字符串的长度(以字节为单位)写入流。此值被写入无符号整数。然后,此方法将大量字节写入流

例如,字符串“A”的长度为1,但使用UTF-16编码时;长度为2字节,因此前缀中写入的值为2,3个字节写入流,包括前缀


Java的
DataOutputStream
DataInputStream
以一种称为修改的UTF-8的格式对字符串进行编码。这基本上意味着单个字符的长度可以是1、2或3字节。假设大多数人将使用ASCII字符,它的目的是在更为压缩的庄园中编写字符串。编码数据中的前导位用于确定后面是否有另一个字节是同一字符的一部分

据我所知,C#的
BinaryWriter
BinaryReader
只是对原始UTF-16数据进行编码

最简单的解决方案是写入字节数组而不是字符串

在C#中,您将需要以下内容:

    InetAddress ip = InetAddress.getByName("localhost"); 

    int PORT_NO = 2000; 
    Socket socket = new Socket(ip, PORT_NO); 

    // obtaining input and out streams 
    DataInputStream reader = new DataInputStream(socket.getInputStream()); 
    DataOutputStream writer = new DataOutputStream(socket.getOutputStream());

    writer.writeChars("Hello");
    String str = reader.readUTF();
byte[] bytes = Encoding.UTF8.GetBytes(str);
writer.Write(bytes.Length);
writer.Write(bytes);  

int len = reader.ReadInt32();
byte[] bytes = reader.ReadBytes(len);
string str = Encoding.UTF8.GetString(bytes);
在Java中,您需要:

byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
writer.writeInt(bytes.length)
writer.write(bytes, 0, bytes.length);  

int len = reader.readInt();
byte[] bytes = new byte[len];
reader.read(bytes, 0, len);
String str = new String(bytes, StandardCharsets.UTF_8);
如果愿意,可以将编码更改为其他编码,但在客户端和服务器上必须相同

编辑:

Java更喜欢大端,而C#更喜欢小端,因为其中一个长度必须颠倒。鉴于网络字节顺序是big-endian,我建议在C#端这样做


您面临什么问题?@ChetanRanpariya,服务器似乎没有接收到Java客户端发送的字符串。服务器运行正常。Java的数据流类在扩展UTF中编码字符串。不工作。服务器和客户端都没有给出任何错误消息。做了一点研究,Java的DataOutputStream使用big-endian,而C#的BinaryWriter使用little-endian。您必须反转其中一个长度前缀。后一个代码如何与前一个代码相匹配?你所说的标准红细胞是什么意思?为什么
ReadBytes
以4为参数?我将假设后面的代码指的是字节反转,它们取代了行
writer.Write(bytes.Length)
int len=reader.ReadInt32()
strBytes
应该类似于存储字符串的字节数组,以前称为
bytes
ReadBytes
将它应该读取的字节数作为参数,我们传入
4
,因为32位整数占用4个字节(
32/8=4
)。@user366312您能详细说明不工作的意思吗?我在ideone上尝试了一组类似的代码,效果很好: