Solved

Java client -> C# server - file transfer

Posted on 2009-03-31
20
1,888 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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.

747 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

12 Experts available now in Live!

Get 1:1 Help Now