简体   繁体   中英

Reading a C# byte array in Java

I'm transferring a file from a C# client to a Java server using TCP Sockets. On the C# client I convert the file to a byte array for transmission and send it using a NetworkStream.

On the Java server I use the following code to convert the received byte array back into a file;

public void run()  {

       try {

            byte[] byteArrayJAR = new byte[filesize];
            InputStream input = socket.getInputStream();

            FileOutputStream fos = new FileOutputStream(
                    "Controller " + controllerNumber + ".jar");

            BufferedOutputStream output = new BufferedOutputStream(fos);

            int bytesRead = input.read(byteArrayJAR, 0, byteArrayJAR.length);
            int currentByte = bytesRead;

            System.out.println("BytesRead = " + bytesRead);

            do {

                bytesRead = input.read(
                        byteArrayJAR,
                        currentByte,
                        (byteArrayJAR.length - currentByte));

                if (bytesRead >= 0) {

                    currentByte += bytesRead;

                }
            }

            while (bytesRead > -1);

            output.write(byteArrayJAR, 0, currentByte);
            output.flush();
            output.close();
            socket.close();

        }

        catch (IOException e) {

            e.printStackTrace();

        }
}

The code above works if the received byte array comes from a client programmed with Java but for C# clients the code hangs in the do-while loop at the bytesRead = input.read(...) method.

Does anybody know why the code is hanging at this point for a C# client but not a Java client? According to the output from the println message data is definately being received by the InputStream and is read once at the bytesRead variable initialization, but not during the do-while loop.

Any solutions or suggestions for overcoming this problem would be welcome.

Regards,

Midavi.

You need to send your bytes as sbyte from c# instead of byte .

In addition you should change your do/while loop to a regular while loop. If you have already read everything from the stream in your first call to input.read then you will block on the second call because read will wait for input.

Based on: http://docs.oracle.com/javase/1.4.2/docs/api/java/io/InputStream.html

 int bytesRead = input.read(byteArrayJAR, 0, byteArrayJAR.length);

Reads all available bytes that means your byte-data is alread in byteArrayJAR or am I completly wrong here?

EDIT:

Just checked some of my projects...I send data from Android <=> C# Server Application.

I use String data = input.readLine(); (java) and _sw.WriteLine("Testdata"); (C#)

Since you cannot know the amount of data being sent in advance in the general case, it would be better to receive the data in chunks and ignore the offset into your bigger array. Your code as-is doesn't handle the case very well if the data is larger than your array, nor if it is smaller than the array.

A much simpler case would be to remove the currentByte offset:

InputStream input = socket.getInputStream();
BufferedOutputStream output = new BufferedOutputStream(
    new FileOutputStream("test.exe"));

byte[] bytes = new byte[2048];
int bytesRead;
do {
    bytesRead = input.read(bytes, 0, bytes.length);
    System.out.println("size: " + bytes.length + " read(): " + bytesRead);

    if (bytesRead > 0) {
        output.write(bytes, 0, bytesRead);
    }
} while (bytesRead > -1);

output.close();
socket.close();
input.close();

And I used the following C# code on the client side:

if (!args.Any())
{
    Console.Error.WriteLine("Usage: send.exe <executable>");
    Environment.Exit(-1);
}

using (var client = new TcpClient("localhost", 10101))
using (var file = File.Open(args.First(), FileMode.Open, FileAccess.Read))
{
    file.CopyTo(client.GetStream());
}

Client side results:

C:\temp>csc send.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.


C:\temp>send send.exe

C:\temp>

Server side results:

C:\temp>javac.exe Server.java

C:\temp>java Server
size: 2048 read(): 2048
size: 2048 read(): 2048
size: 2048 read(): 512
size: 2048 read(): -1

C:\temp>test.exe
Usage: send.exe <executable>

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