简体   繁体   中英

Bytearray from c# to java over socket keeps failing after send from java to c#

I am trying to send a byte array from java to c# and then send another byte array from c# to java

Flow of byte arrays as follows Java -> c# Java <- c#

I can get the send java -> c# to work just fine but when I try the send c# -> it just hangs. I have tried just about everything i can find on the web but keep getting the same result. If I comment out the java to c# send then both java and c# work just fine but as soon as I try the send from java to c# both java and c# sit at the respective read and send line.

public void test()
{
    //1. READ
    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
    string input = enc.GetString(ReadNetworkStream(netStream));
    Console.WriteLine(DecryptData(input, ""));

    //2. SEND
    string output = "This is the c# client!!!";
    sendNetworkStream(output, netStream);
}
private void sendNetworkStream(string infoToSend, NetworkStream netStream)
{
    UTF8Encoding encoding = new UTF8Encoding();
    byte[] byteDataToSend = encoding.GetBytes(infoToSend);
    Console.WriteLine(netStream.CanWrite);
    Console.WriteLine(byteDataToSend.Length);
    netStream.Write(byteDataToSend, 0, byteDataToSend.Length);
    netStream.Flush();
}

private static byte[] ReadNetworkStream(NetworkStream netStream)
{
    byte[] buffer = new byte[1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = netStream.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
 }

I appreciate any help, Thanks.

I think that the problem lies within the sendNetworkStream method. You are flushing the stream but not closing it. Using the .close() method at the very end should close the stream. On the other side, your Java application is waiting for the stream to be closed, hence it 'hangs'.

You are using the Read method on the NetworkStream , which blocks when there is no data available. See here in the comments: http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.read.aspx

The default is for Read to block when there is no data, but you can specify a timeout in milliseconds using the ReadTimeout property. However when it times out Read does not return 0 but throws an exception.

You are also trying to read until the end of the stream, since the stream is not closed by either the Java or .NET application - that is, you are using the same stream to both read and write.

When the Java program read is commented out, the program terminates and this closes the network stream. Therefore the C# program successfully unblocks the Read call and completes successfully.

However, when the Java program tries to read after it sends, the network stream remains open, and the C# program also tries to read from it. Now two programs are trying to read, and both blocking and waiting for the other.

How this is usually solved is by using a protocol of some sort. Protocols tell each program how much data to read at each point in the various exchanges, so they don't sit there waiting. Sometimes it's done by using special magic characters, other times by first sending the number of bytes to read etc.

If you don't want to do this, you can:

  • Make it so that Read does time out after a while (and decide what to do from there); and/or
  • Use separate streams for reading and writing from the two clients, but still noting at which points each application blocks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM