我正在制作一个.NET应用程序,该应用程序应该通过套接字与Java应用程序进行通信。 这是.NET代码:
string str = " MSG1234";
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 8080);
byte[] msg = Encoding.UTF8.GetBytes(str);
client.Client.Send(msg);
StreamWriter sw = new StreamWriter(client.GetStream());
StreamReader sr = new StreamReader(client.GetStream());
while (true)
{
Console.WriteLine(sr.Read());
}
问题在于Java应用程序不会发送答案。 该应用程序是第三方软件,我无法更改,但是我下载了一个反编译器,并在Java类中找到了相关的代码:
try {
while (this.is.available() <= 0);
body = new byte[this.is.available()];
this.is.readFully(body);
System.out.println("Message received");
} catch (Exception e) {
System.out.println("Error: " + body);
}
在这种情况下,“ is”是DataInputStream。 这是发生的情况:1.我创建一个套接字并发送消息2.等待响应,什么都没发生3.我手动关闭应用程序-导致套接字到期4.突然,整个消息出现在Java应用程序的日志中。 这意味着发生了异常,并且体内确实有东西。
您能否指出我的错误可能出在哪里? 我相信this.is.readFully(body)行不应存在,但我不确定。 也许我应该手动从C#代码发送EOF,但是我无法找到方法。
该代码的另一个小问题是,删除了消息的前两个字符,这就是为什么我在实际消息的前面加上了两个空格。
先感谢您。
编辑
所以我试图用一些随机数据填充套接字,我终于得到了答案:
for (int i = 0; i < 600; i++)
{
sw.Write("some long random string");
sw.Flush();
}
不过,这不是一个好的解决方案,因为我发送的消息必须准确。 然后我尝试在soc.Disconnect(false);
发送相关数据后关闭套接字soc.Disconnect(false);
这会导致Java应用程序的日志填充正确的调试信息。 有什么方法可以将EOL发送到套接字,以便Java应用停止监听并开始发送数据吗? 谢谢。
编辑2我试图创建一个Java客户端来连接到服务器,发生了同样的事情。
然后,我创建了一个虚拟服务器,以在与我也要连接的Java应用程序相同的端口上进行侦听,它的行为也与Java应用程序应有的方式相同,并且正在运行。
现在,我感到我唯一的机会是将EOT或EOF命令发送到流,但是我不知道如何在.NET上进行操作,也无法在Internet上找到答案。
如果Java应用程序来自第三方,则可能是您做错了什么。 DataInputStream.readFully(byte[])
函数将阻止应用程序,直到它读取了字节数组可以容纳的字节数,因此您拥有的代码段来自于读取操作。
我还看到您使用Socket.Send(byte[])
函数与Java应用程序进行通信,我建议您使用诸如StreamWriter或BinaryWriter的更高级别的东西,而不是像这样:
StreamWriter = new BinaryWriter(client.GetStream());
StreamWriter.Write(msg);
StreamWriter.Flush();
你可以尝试来刷新 StreamWriter
(所以它写入其缓冲区的流对象)和实际NetworkStream
你有client.GetStream()
所以它发送一个数据包,尽管包不是“全”了吗)?
NetworkStream ns = client.GetStream();
StreamWriter sw = new StreamWriter(ns);
StreamReader sr = new StreamReader(ns);
// ...
sw.Flush();
ns.Flush();
最有可能的是,您并没有冲洗所有需要冲洗的东西。 您是否尝试过使用Wireshark等进行网络通信-数据实际上在输出吗? 如果不是,则问题出在您的.NET代码中。