Sending List through DatagramSocket? - java

I have a spreadsheet application in Java, and one of the features it provides (which I developed) is sheet sharing. Basically, anyone can be a client or a server because the app has both server and client code. The user who is the server creates the share, specifies the IP, and then the share is created and active (best case scenario) with the server listening for clients on its IP and selected port.
For auto-discovery, I am using DatagramSockets via UDP broadcasts, while the 'real communication' is TCP-based (after the client is already connected). However, I'm trying to send a List through that UDP socket and I don't know how to do it. That List contains the active shares on the server that I need to send to the client so it knows what it can connect to.
It goes like this:
Client -> looks for active servers by sending a packet to the network -> server listens and sends a packet back. This packet should be the List (if it is possible to send it via these kind of sockets).
Can anyone shed some light on my question? Thank you.

You can convert your List to a byte[] before sending, and convert it back to a List on the reciever using Java Serialization.
// Sender
List list = new ArrayList();
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(out);
outputStream.writeObject(list);
outputStream.close();
byte[] listData = out.toByteArray();
// Reciever
ObjectInputStream inputStream = new ObjectInputStream(new ByteArrayInputStream(listData));
list = inputStream.readObject();
Just make sure all the objects you put in your List implements Serializable.

Related

Java won't deserialize object after it is sent through socket stream

I'm trying to create application that will send object through local network using Sockets. When i run server and client code in Intellij Idea they work fine, but when i run server code on one pc and client code on another pc i get errors like java.io.StreamCorruptedException: invalid type code: 00 or java.io.StreamCorruptedException: invalid stream header: 6C69656E
byte[] readBuffer = new byte[4096];
int num = inStream.read(readBuffer); //inStream is socket input stream
ByteArrayInputStream bis = new ByteArrayInputStream(readBuffer);
ObjectInput in = new ObjectInputStream(bis);
Object o = in.readObject(); //this line throws error
The thing is that writing and reading object to socket stream works on server (which is on pc where i created project) but reading from input stream on client (another pc where i copied project) throws error.
Can someone help me with this? I searched everywhere for solution but i can't figure out what is problem with serializing, because it works on same pc but won't on another. Is there any way that i can make this pc independent? This also happens when i create jar files and run it on same pc where it works in Intellij Idea.
It can because that client didnt read message fully.
But the real mistake is that you work with TCP socket like a message protocol transport but TCP is a stream protocol so you have to create your own message protocol on top of TCP.
Why it works fine on local system?
Because transport data between client and server happen too fast in local test and maybe in just one frame so all the message transported in just one IO-call but in internet or a network it doesn't work like you think.
There is 2 way to handle this mistake:
1- Pass SocketInputStream directly to ObjectInputStream instance and let it handle read objects.
2- Create a message protocol for example you can put the size of message in 2 or more first bytes. Then you can workd like this :
Read 2(or more) first bytes and detect size of packet.
Create a buffer for this size and read packet bytes.(make sure you read all of packet data from socket . You can use return value of SocketInputStream.read(byte[]) method to calculate it)
Pass the packet to ObjectInputStream and read object !

How can socket Server catch data from client just in the moment when client send it?

The program consist that I have to send a byte from by Android app to a Wifi Access Point, then this byte is interpreted by a hardware device.
I can send byte to client and it receives the byte correctly (and more bytes, don't know why, maybe because protocol). Hardware filter protocol bytes and catch only the correct one.
There's is how i send it (byte es created previously in another method, but it's correct):
public static void sendByte (Byte data) throws IOException {
DataOutputStream output;
Socket client;
client = new Socket("1.2.3.4", 2000);
output = new DataOutputStream(client.getOutputStream());
output.write(data);
output.close();
client.close();
Log.w("INFO","Data sended");
}
When I send the byte, hardware part change the color of a light, and it happens successfully.
I putted this 3 lines too:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Until here there's no problem.
Then I want to receive from that hardware bytes too. Imagine that someone change the color of that light, I want to know it. So I created a receiving method:
public static String readByte() throws IOException{
InputStream input;
DataInputStream iData;
String data = null;
try {
byte[] bytes = {0, 0, 0, 0, 0, 0, 0, 0};
Socket server = new Socket(2000);
Socket client = server.accept();
input = client.getInputStream();
iData = new DataInputStream(input);
Scanner scanner = new Scanner(iData);
iData.skip(0);
iData.read(bytes, 0, 8);
data = bytesToHex(bytes); //A simple method that change bytes to hex, this method it's correct
Log.w("READ", "" + data);
input.close();
client.close();
server.close();
}catch(IOException e){
Log.w("EROR","No es pot conectar");
}
return data;
}
Here I create a server that connects to client to get data (I don't know if it's necessary to create a server). The problem is that I always receive 7 bytes, and they are always the same, I used skip(7) to skip the protocol bytes, but then I don't receive anymore bytes.
I know that the hardware send bytes through the wifi where I'm connected, but I can't catch them.
_________TO SUM UP_________
I think the problem is that I can't catch the bytes because the hardware part simply send me, and my Android app can't store it. I would like to read the byte just when hardware sends me it, or something like this. I searched methods everywhere and object attributes and I can't find a solution to this :(
Thanks for your attention.
Wanted to know to if ServerSocket is strictly necessary or not.
When java program sends data to hardware, at that time, java program is the client and hardware is the server.
When the hardware sends data to java program, the hardware is the client and your java program is the server.
So, in your java program, you need to have two threads, one client thread (with a Socket to send bytes) and a server thread (with a ServerSocket, lets say for example, on port 8999) to receive bytes.
For the hardware to send you the bytes, it needs the following details.
1. IP Address or host name of the device on which your java program runs.
2. The port in which the ServerSocket is listening (8999 in our case).
If your hardware manual says it can send data to you, then, I am sure you can configure these details somewhere. (I am not sure what your hardware is. So, look at your hardware manual about how to configure these details).
Sometimes, the device can send response on the same Socket you opened. (Again, I am at a loss how it is done in your hardware. Refer your hardware manual). In such case, keep your socket open and read from it in a separate thread.

Android programming: Change TCP to RTP

I am working on an Android app including client and server that client app sends camera captured data to server for processing, and server sent the result back to client to display. The current version of it uses TCP for transmitting data, so the code includes something like:
Client side:
send(){
Socket socket = new Socket();
DataOutputStream outputStream = new DataoutputStream(socket.getOutPutStream());
outputStream.writeUTF(...)
...
outputStream.write(data);
outputSteram.flush();
...
}
receive(){
DataInputStream dataInputStream = new DataInputStream(...);
...
dataInputStream.readFully(data, 0, length);
...
}
Server side:
...
serverDataInputStream.readFully(data,0,length);
//process data
...
serverDataOutputStream.write(reply)
...
I tried to change this to use UDP, but the data sent from client to server is much larger than the maximum size of a UDP packet, so have to fragment the data in client and reassemble it on server manually. It turns out to be too much troublesome.
I know RTP takes care of data fragmentation, so now I want to change this into RTP. After Googleing for a while, I found the following information:
http://sourceforge.net/projects/jlibrtp/
http://code.google.com/p/sipdroid/source/browse/trunk/src/org/sipdroid/sipua/ui/VideoCamera.java
And these two posts are very similar to what I am doing:
Android Camera RTSP/RTP Stream?
Creating RTP Packets from Android Camera to Send
But the posts just include limited sample code. Can anyone post more details and sample code here? I don't have much experience of Java and Android programming. So detailed examples or step by step instruction will be extremely appreciated!
Thank you!

Client / server communication using serialized objects

I try to establish a client / server connection for a mastermind game.
I though of using enumerations to represent the different pegs and made them serializable.
Then I have to implement the connection, using serversocket and getting the socket using accept and so on.
Once the connection is established, I first have to read for client objects, and it is where I am having problems...
Here is a piece of my code, which produces EOFException before I could ever do anything!
(the client data is send on user's interaction).
ObjectInputStream ois =
new ObjectInputStream(socket.getInputStream());
ArrayList<Peg> combination = new ArrayList<Peg>();
do
{
combination.clear();
for (int i = 0; i < 4; i++)
{
combination.add((Peg)ois.readObject());
}
}
while (!checkCombination(combination));
ois.close();
socket.close();
Thank's in advance
We need more details. How are you syncing up writes from the client and the reads on the server? Can you post more details?
BTW, is using raw sockets an absolute requirement? If not, try out RMI which does what you want to do with much less hassle (i.e. sending across Java objects transparently and much more).
If you are getting an EOFException it means the other end has closed the connection.
If you want to send a list, just send the list. i.e.
// on the sender
List<Peg> list =
oos.writeObject(list);
// on the receiver
List<Peg> list = (List<Peg>) oid.readObject();

to read the packet of bytes on client(client Socket) from server(ServerSocket) using java

i m a new .
i m a java developer(fresher) and currently i m working on BSE project and i m facing problem to read the packet of bytes on the client(client socket) from the server(server socket). if u can help me then please help me.
Thanks in advance
Well, if you want to interact directly with packets, then you need to use a DatagramSocket instead of the regular Socket and ServerSocket.
Then, you should visit this link to see a good tutorial on how to get started with sending and receiving individual packets.
The basic idea is that the Client or Server will block on the recieve() call while it waits for its partner to send a packet using send().
If you aren't interested in the individual packets like you indicated in your question, then you will want to use Socket and ServerSocket. The first step to communicating between the two involves code that will look similar to the following:
//Server
// this call will block until the client tries to connect to the server
Socket cientConn = new ServerSocket(8878).accept();
// now you can use the connection's input and output streams to send data
/******************/
// Client
Socket serverConn = new Socket(addressOfServer, 8878);
// now you can use the connections input and output streams
After you get connections set up, you will have basically 2 read/write loops. One on the client, and one on the server.
while(true) [
// check for data from an input stream
...
// respond with message back
}
You will need a similar loop for the client and the server.

Categories