2013-02-25 79 views
2

我正在制作一个.NET应用程序,它应该通过套接字与Java应用程序进行通信。 这里是.NET代码:C#<-> Java套接字通信

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); 
} 

“是”,在这种情况下是DataInputStream类。这是发生了什么: 1.我创建一个套接字和发送邮件 2.我等待回应,什么都不会发生 3.我手动关闭应用程序 - 它会导致插座到期 4.突然出现在整个邮件Java应用程序的日志。这意味着发生了异常,并且实际上有一些东西在体内。

你能指出我错误的地方吗?我相信this.is.readFully(身体)线不应该在那里,但我不确定。也许我应该手动从C#代码发送一个EOF,但我无法知道如何。

另外,与代码小问题是,该消息的前两个字符被剥夺,这就是为什么我已经包括在实际消息的前面的两个空间。

预先感谢您。

编辑

所以我试图填补一些随机数据插口和我终于得到了答案:

for (int i = 0; i < 600; i++) 
{ 
    sw.Write("some long random string"); 
    sw.Flush(); 
} 

这不是一个很好的解决方案,但因为消息我发送必须是确切的。 然后我试图通过soc.Disconnect(false);发送相关数据后关闭套接字,这会导致Java应用程序的日志填充正确的调试信息。 有什么方法可以将EOL发送到套接字,这样Java应用程序就会停止监听并开始发送数据? 谢谢。

EDIT 2 我试图创建一个Java客户端连接到服务器,同样的事情发生了。

然后我创建了一个虚拟服务器监听同一端口的Java应用程序,我也连接上,它也表现方式与Java应用程序应该和它的工作。

现在我觉得我唯一的机会是发送EOT或EOF命令到流中,但我不知道如何在.NET上执行它,我也无法在Internet上找到答案。

+0

我认为这个问题可能是假设在一面上写入的一个字节会瞬间出现在另一面。强烈建议:阅读[Beej的套接字编程指南](http://beejjus.com/guide/bgnet/output/html/multipage/) – paulsm4 2013-02-25 23:22:40

+1

您是否尝试过在发送后调用Flush方法?如果您发送的数据块很小,我认为您可能会与Nagle的算法发生冲突。 – 2013-02-25 23:25:33

+0

如果其他应用程序不回答您的问题,那么您可能会做错某些事情。应用程序使用什么协议,您是否发送了有效的消息?你是如何决定发送什么的,你如何表示你已经发送了? – CodeCaster 2013-02-25 23:40:50

回答

1

如果Java应用程序是由第三方,有机会,你正在做的事情是错误的。 DataInputStream.readFully(byte[])函数会阻塞应用程序,直到它读取了字节数组可以容纳的字节数为止,因此您拥有的代码片段来自读取操作。

我也看到您使用Socket.Send(byte[])功能与Java应用程序通信,我建议你使用的东西更高的水平一样的StreamWriter或的BinaryWriter,更多像这样少:

StreamWriter = new BinaryWriter(client.GetStream()); 
StreamWriter.Write(msg); 
StreamWriter.Flush(); 
+0

我试过StreamWriter WriteLine或写入和冲洗后,它也没有帮助。我试过的是这样的: for(int i = 0; i <600; i ++) sw.Write(“some long random string”); sw.Flush(); } 它引发服务器的响应。我必须填写整个缓冲区或其他东西。这真的很奇怪。 – user2109153 2013-02-26 06:05:02

0

你可以尝试刷新StreamWriter(所以它写入其缓冲区的流对象)和实际NetworkStream你从client.GetStream()(所以它发送一个数据包,尽管数据包还没有“全”呢)?

NetworkStream ns = client.GetStream(); 
StreamWriter sw = new StreamWriter(ns); 
StreamReader sr = new StreamReader(ns); 
// ... 
sw.Flush(); 
ns.Flush(); 

最有可能的是,你没有冲洗你需要冲洗的所有东西。您是否尝试过使用例如wireshark - 数据实际上是out?如果没有,问题出在你的.NET代码中。

+0

我已经尝试了rawcap,因为它发生在回送上,并且是的,数据实际上正在正确传输。我也尝试了NetworkStream刷新,并没有帮助。 – user2109153 2013-02-26 10:58:46

+0

然后尝试接下来编写自定义Java侦听器,并查看是否有效。 – 2013-02-26 13:57:56

+0

我已经完成了。首先,我为服务器创建了一个Java客户端,它显示了同样的问题。然后,我创建了一个Java服务器,并使用相同的.NET代码进行连接,并且它正在工作。 – user2109153 2013-02-26 16:49:16