Link to home
Start Free TrialLog in
Avatar of Strs
Strs

asked on

Java client -> C# server - file transfer

Hi,

I have a client applet for file uploading to a .NET c# application server. It's very easy, just establishing a socket connection and using a java OutputStream to send the file bytes as a byte array to the c# server app, reading a NetworkStream and writing it down to a file.

It all works quite well, but when I get to the byte 255 (signed byte -1 in java) the c# app reads it as 10. This is the only one I've identified as wrong so far. Other >127 bytes seems to work fine. And strange thing is it works correctly on my dev machine. On the server this strange 255 -> 10 problem appears. This makes a text file work, but a bitmapped image doesn't.

Anyone has any clue about how to get around this? I'm running the same .NET versions on the server as on my dev machine. Thanks for any help with this!

(the reason for not using java as server app, is that I already have .NET libraries that help a lot with building this server)
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

You need to decode into unsigned bytes on the C# side. Are you doing that?
Avatar of Strs
Strs

ASKER

I have tried that, but don't know what good it does..? When I'm printing the bytes the decoded signed bytes on the c# side still translates as 10, but on the corresponding java side they are -1 (or converted to [unsigned] int: 255). And other signed negative bytes translates correctly to >127 values on the c# side. This really puzzles me...

Java runtime output (first number is [signed] byte sent in outputstream, second is & 0xff):

byte 16: -1 255
byte 17: -1 255
byte 18: -1 255
byte 19: 119 119
byte 20: 30 30
byte 21: 114 114
byte 22: -115 141

C# runtime output (first number is converted sbyte[] value, second is byte[] value from networkstream):

byte 16: 10 10
byte 17: 10 10
byte 18: 10 10
byte 19: 10 10
byte 20: 30 30
byte 21: 114 114
byte 22: -115 141

As you can see the 19:th byte is also converted (because it follows the 255 bytes?)
It might be an idea to post the C# code
how are you writing/reading a byte?
Are you using matching endian?

Avatar of Strs

ASKER

CEHJ: C# and java code attached.

objects: Actually... I don't know. Tried to find info about matching endians and NetworkStream but no luck... Am I missing something? (of course I am otherwise this would work) :-)
// java code sending bytes (simplified)
 
File file = applet.getFile(0); // gets the current file to transfer
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = socket.getOutputStream();
byte[] bytes  = new byte[blockSize];
bis.read(bytes, 0, bytes.length);
os.write(bytes, 0, bytes.length);
 
// c# code reading bytes (simplified)
 
NetworkStream inBytes = client.GetStream(); // client is a TcpClient
byte[] bytes  = new byte[blockSize];
FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
int bytesRead = inBytes.Read(bytes, 0, blockSize);
fs.Write(bytes, 0, bytesRead);

Open in new window

Can you just dump the *first* few (say 16) bytes of

a. source file
b. what C# receives after inBytes.Read
Avatar of Strs

ASKER

Ok,

Java (sending) - first value is [signed] byte, second value is byte & 0xFF

byte 0: 71 71
byte 1: 73 73
byte 2: 70 70
byte 3: 56 56
byte 4: 57 57
byte 5: 97 97
byte 6: 5 5
byte 7: 0 0
byte 8: 5 5
byte 9: 0 0
byte 10: -60 196
byte 11: 0 0
byte 12: 0 0
byte 13: 0 0
byte 14: 0 0
byte 15: 0 0
byte 16: -1 255

c# Receiving - first value is converted sbyte, second value is byte from NetworkStream

byte 0: 71 71
byte 1: 73 73
byte 2: 70 70
byte 3: 56 56
byte 4: 57 57
byte 5: 97 97
byte 6: 5 5
byte 7: 0 0
byte 8: 5 5
byte 9: 0 0
byte 10: -60 196
byte 11: 0 0
byte 12: 0 0
byte 13: 0 0
byte 14: 0 0
byte 15: 0 0
byte 16: 10 10
Your approach on the Java side could be dubious - you must read to EOF. See the following for how to copy a stream

http://www.technojeeves.com/joomla/index.php/free/51-copying-streams
thats irelevant
One significant difference between your code and the code at the link i posted is that your read goes:

>>
bis.read(bytes, 0, bytes.length);
os.write(bytes, 0, bytes.length);
>>

The problem with that is that read does not guarantee to read the number of bytes you want it to read (bytes.length) and if it doesn't, will simply corrupt the output stream, since you will copy bytes left over from the previous read, or null, if there wasn't one.

See the code at the link i posted for the correct pattern for copying
Avatar of Strs

ASKER

I simplified a bit too much in the code above. I was already collecting the bytesRead int and using in the write. However I simplified the original java code now (see below). It didn't make any difference.




int bytesRead;
while((bytesRead = bis.read(bytes)) > -1){
   os.write(bytes, 0, bytesRead);
   // debug - for comparing bytes with receiving app
   for(int i = 0; i < bytesRead; i++){
      System.out.println("byte " + i + ": " + (bytes[i]) + " " + (bytes[i] & 0xff));
   }
}

Open in new window

Avatar of Strs

ASKER

object: I don't know much about endians, so I did some research. It seems it has to do with byte order, and since the bytes sent and received is exactly the same on most positions (except 16, 17, 18, 19 in my example) - can that really be the problem here..?
>>can that really be the problem here..?

No ;-)
Can you put some debug on the C# side so we can see what's *going* to be written to the disk, not what *has* been written?
Avatar of Strs

ASKER

The output i have provided is directly from the stream, from the bytearray i read the data into, before writing to file.

I discovered the error when trying to open a transferred .jpg file, but then started to examine the bytes before writing them to the filestream.
OK - still thinking ;-)
Avatar of Strs

ASKER

No more clues..? Anyone?
ASKER CERTIFIED SOLUTION
Avatar of Strs
Strs

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thats a good way to stop people using that port :)
@Strs - can you post please the source code for transfering files? I use Java(Android) as client and C# as Server.

thanks advanced