Solved

Java client -> C# server - file transfer

Posted on 2009-03-31
20
1,897 Views
Last Modified: 2013-11-05
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)
0
Comment
Question by:Strs
  • 8
  • 8
  • 3
  • +1
20 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 24032521
You need to decode into unsigned bytes on the C# side. Are you doing that?
0
 

Author Comment

by:Strs
ID: 24033121
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?)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24033195
It might be an idea to post the C# code
0
 
LVL 92

Expert Comment

by:objects
ID: 24034385
how are you writing/reading a byte?
Are you using matching endian?

0
 

Author Comment

by:Strs
ID: 24036537
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

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24037367
Can you just dump the *first* few (say 16) bytes of

a. source file
b. what C# receives after inBytes.Read
0
 

Author Comment

by:Strs
ID: 24037465
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
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24037576
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
0
 
LVL 92

Expert Comment

by:objects
ID: 24037583
thats irelevant
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24038014
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
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Author Comment

by:Strs
ID: 24038693
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

0
 

Author Comment

by:Strs
ID: 24039299
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..?
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24039335
>>can that really be the problem here..?

No ;-)
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24039425
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?
0
 

Author Comment

by:Strs
ID: 24041198
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.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 24041472
OK - still thinking ;-)
0
 

Author Comment

by:Strs
ID: 24147433
No more clues..? Anyone?
0
 

Accepted Solution

by:
Strs earned 0 total points
ID: 24295868
This has been solved. It had nothing to do with Java or c#. I tried using port 21 for the file transfer, but when I changed to another port it started to work. It must be a firewall or other server issue with the FTP-ports. I don't get it why it changes 255-bytes to 20, but now it works anyway (using port 119 instead until I find a better one).
0
 
LVL 92

Expert Comment

by:objects
ID: 24299923
thats a good way to stop people using that port :)
0
 
LVL 13

Expert Comment

by:Molnar István
ID: 37398634
@Strs - can you post please the source code for transfering files? I use Java(Android) as client and C# as Server.

thanks advanced
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now