Sending and receiving data using Sockets - java

i'm trying to learn more about networking so i decided to do a small project using sockets. I have already been successful is creating an echo server which i know is pretty basic.
The next step would be to send all kinds of files (text files, images maybe even videos?) from the server to the client and vice versa. I have been trying to do so with FIleOutputStream, ObjectOutputStream (and input obviously) and i even tried Byte Buffer but by reading the Java docs i'm starting to understand that i really dont know much about Data....
so my questions are:
Can I convert all type of data (text, images, videos) into bytes, send it and then convert it all into the data that it used to be, or do i need a specific function for each type of data?
Can I convert a text file or an image into an Object and then send it with ObjectOutputFile? If so then how can i decompress it in the other side? I've tried ObjectOutputFile.readObject but i dont really know what to do after that.
Here's what I've been trying to do (I won't post all the code because, only this particular part is important i believe:
Server: (out is a DataOutputStream)
ObjectOutputStream oos = new ObjectOutputStream(out);
Path path = Paths.get("stuff/Folder.jpg");
byte[] data = Files.readAllBytes(path);
oos.write(data);
client (in is a DataInputStream):
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
Thanks for all the help in advance, if you think that you know an article or a tutorial that would help me learn more about this it will also help!

Can I convert all type of data (text, images, videos) into bytes, send it and then convert it all into the data that it used to be?
Sure.
Or do I need a specific function for each type of data?
That's not an "or" - if you want to convert several types of data into bytes yourself, then you probably need a separate function for each type. Note that if you are sending files, you don't need any conversion because the content of a file is already just bytes.
Can I convert a text file or an image into an Object and then send it with ObjectOutputFile?
You could send it with ObjectOutputStream.
If so then how can i decompress it in the other side?
With ObjectInputStream.
I've tried ObjectOutputFile.readObject but i dont really know what to do after that.`
There is no such method in Java as ObjectOutputFile.readObject.

it is pretty certain that you can convert any data into bytes. However, the problem is how you could convert it back? Typically, we use Base64 encoder to encode image and when clients get that we can convert it back by Base64 decoder. There is a lot of way to do this. Please Google it.
Yes, you can use Object data to send. You may need to define a new class for the object and then call data back by getter. In client side, you need to declare the Object value as ois.readObject(). Like:
Object object = ois.readObject();
Just add a little bit advice, I feel you are not so familiar with socket right now. So, a text book like Computer Networking(Kurose Ross) will be helpful. Also, if you plan to transmit data between C and Java, then you cannot use Object because C does not support it natively.

Related

Sending Serialized Data

Basically I am doing some networking with a client and server sending "packets" back and forth to each other. I have it working with basic variable data such as ints or strings passing back and forth, however now I want to pass an object.
So I know I have to serialize the data of the object to pass it through the socket. That is working as well (as I can get the correct information if I serialize then de-serialize right away) but the problem comes in when my server receives a packet.
My server interprets packet data based on the first 2 characters of the packet. So 01foobar is a type of packet correlating to whatever "01" is assigned to and 02foobar is a different packet as well. So I don't know the best way to do this with an object attached. What is mean is this...
The way I have tried to do it right now is, serialize my object and get it's string. Then append on 03 to the front. So basically I have a string that looks like 03[B#3e9513b7 (or whatever) then do getBytes() on that string which gives me another byte[] (so I can send it through the socket). Then when the server receives that information, I can append the 03 off and I'm left with just [B#3e9513b7. The problem is, [B#3e9513b7 is now a string, and not a byte[] and in order to deserialize I need to send it the same byte[] as it gave me when it serialized that data. So that got me looking into a way to make [B#3e9513b7 BE the byte[] (aka, so when I do toString() on that new byte[] it returns [B#3e9513b7) but was having issues assigning it like that because it would give me a new byte[] for [B#3e9513b7 as a string. So obviously then, when I send it to be deserialized it has a byte[] that it doesn't know what to do with and throws an error.
So I have to imagine there's a better way to do this, and I'm just making things more complicated than they should be. Any recommendations? I can provide code snippets if needed.
Thanks guys!
Edit: I guess I should mention that I am using Java with using UDP sockets.
If you are looking for a reliable and efficient solution for client-server communication, I would suggest to look at Netty.
Regarding how to serialize/deserialize your objects, you have many choices as Java serialization, XML, JSON ...
You would have to pass your serialized objects in UDP datagrams. However, be aware that UDP datagram size is limited. If you're exchanging big objects, you may want to switch to TCP transport which is more reliable.
You may also want to look at SOAP/REST web services.

sending serialization file via sockets in java

System.out.println("Java is awesome!");
Pardon my enthusiasm; I just can't believe how powerful Java is, what with its ability to not only save objects (and load them), but also with its main purpose, to send them over a network. This is exactly what I must do, for I am conducting a beta-test. In this beta-test, I have given the testers a version of the game that saves the data as Objects in a location most people don't know about (we are the enlightened ones hahaha). This would work fine and dandy, except that it isn't meant for long-term persistence. But, I could collect their record.ser and counter.bin files (the latter tells me how many Objects are in record.ser) via some client/server interaction with sockets (which I know nothing about, until I started reading about it, but I still feel clueless). Most of the examples I have seen online (this one for example: http://uisurumadushanka89.blogspot.com/2010/08/send-file-via-sockets-in-java.html ) were sending the File as a stream of bytes, namely some ObjectOutputStream and ObjectInputStream. This is exactly what my current version of the game is using to save/load GameData.
Sorry for this long-winded intro, but do you know what I would have to do (steps-wise, so I can UNDERSTAND) to actually send the whole file. Would I have to reconstruct the file byte-by-byte (or Object-by-Object)?
Its pretty simple, actually. Just make your objects serializable, and create an ObjectOutputStream and ObjectInputStream that are connected to whatever underlying stream you have, say FileInputStream, etc. Then just write() whatever object you want to the stream and read it on the other side.
Heres an example for you.
For sockets it will be something like
ObjectOutputStream objectOut = new ObjectOutputStream(serverSocket.getOutputStream());
ObjectInputStream objectIn = new ObjectInputStream(clientSocket.getInputStream());
Java Serialization is an immensely powerful protocol. java.io.ObjectOutputStream and java.io.ObjectInputStream are the higher level classes which of course are wrapped with the lower level classes such as FileInputStream and FileOutputStream. My question is why do you wish to read the file byte by byte when the entire file can be read in Objects.
Here is a good explanation of the procedure.
http://www.tutorialspoint.com/java/java_serialization.html

How to save an input stream into a variable when you don t know it 's type?

I am using TCP Sockets and I am a beginner in Java and Sockets too. The scenario is that the client,depending on server 's answer, may send either int or a string. I need to save the output stream of the client, in a variable on the server 's side, so i can use it in if statements and so on. But how could I do this when i don t know if the stream sent is an integer or a string?
I have made a very simple example, because my code is huge and messy and i don t want to make it more complex
Client Side:
serverSentence=inFromServer.readLine();
if (serverSentence.equals("Hello"))
{
anInt=readUserInput.nextInt();
outToServer.write(anInt);
}
else
{
outToServer.writeBytes("Hello word!"+'\n');
}
So how I could do this, I mean saving in a variable the Client 's output stream, in the Server 's side (or the opossite), so I could use it in loops and ifs?
Use Object. A reference typed as an Object may refer to Integer or String. Another story is of course deserializing the incoming data as either. If the problem has to do with not knowing how to interpret serialized data, include some sort of flag to indicate what the data is.
You should design your protocol of communication between server and client in such a way that server would be able to read some information (you could call it standard header), and based on that would know how to interpret the remaining bytes sent by the client.
And then you'll know how to read the data from client, and where to store it.

Java reading from comport

Problem: Trying to read from some electronic scales using the comport via Java
I am trying to read from a com port using Java. So far I have been successfull in creating a small application that uses the Java SerialPort and InputStream classes to read from the comport.
The application uses a SerialPortEventListener to listen to event sent via the comport of the scale to the computer. So far I have had some success by using an InputStream inside the event listener to read some bytes from the comport, however the output does not make any sense and I keep getting messages in the form of:
[B#8813f2
or
[B#1d58aae
To clarify I am receiving these messages on screen when I interact with the keypad of the scale. I just need some help on interpreting the output correctly. Am I using the correct classes to read and write to the comport?
You have read the data into a byte[], and then attempted to dump it by using System.out.println(data) where data is declared byte[] data. That, unfortunately will just print the array's internal representation, which is, uselessly, '[' followed by the hex hash code.
Instead, you want to dump the contents of the array. Using
System.out.println(Arrays.toString(data))
is the simplest way which should work for you.
Otherwise, you need to iterate the array, and print each byte, or transform the byte array to a String using, for example, new String(data) (which will use the platform default encoding).
Those look like the result of printing a byte array object as a raw object reference. So your call has some sort of confused call to System.out.something or System.err.something, most likely.
The object you have there is apparently a byte array. I take it you're taking the object and printing it to the console.
See: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getName()
and: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#toString()

How can I send data in binary form over a Java socket?

I've seen lots of examples of sending serialized data over sockets in Java, but all I want is to send some simple integers and a string. And, the problem is I'm trying to communicate these to a binary written in C.
So, bottom line: how can I just send some bytes over a socket in Java?
You can use the simple OutputStream given by the Socket.
From there you can write bytes.
If you want you can also encapsulate this stream in a BufferedOutputStream to have a buffer.
I would really recommend not using the Java Sockets library directly. I've found Netty (from JBoss) to be really easy to implement and really powerful. The Netty ChannelBuffer class comes with a whole host of options for writing different data types and of course to can write your own encoders and decoders to write POJOs down the stream if you wish.
This page is a really good starter - I was able to make a fairly sophisticated client/server with custom encoders and decoders in under 30 minutes reading this: http://docs.jboss.org/netty/3.2/guide/html/start.html.
If you really want to use Java sockets. The socket output stream can be wrapped in a DataOutputStream which allows you to write many different data types as well, for example:
new DataOutputStream(socket.getOutputStream()).writeInt(5);
I hope that's useful.
I would recommend looking into Protocol Buffers for the serialization and ZeroMQ for the data transfer.

Categories

Resources