J
Jan Liße
I'm stuck on what it seems like a simple problem: I need to send an object
over a network socket. Additionally i use a simple home-brew
communication-protocol
based on text messages.
1.) My object is a char[] [], representing the grid of a game.
I assume it must be serializable by default.
2) I have got a NetWorker class, which implements the run method for
receiving
data running in a separate thread. Furthermore the class has two more
methods,
one for sending text commands, and one for sending objects.
In the run-method i open up an ObjectInputstream
on my socket to listen first for a text-command with readUTF().
When it receives a command called "Object coming" it should switch the
ObjectInputStream to readObject(). The constructor of the
netWorker-class
requires a socket-object and a NetWorkerListener object which is my
main-class that implements
that listener-interface to bubble up the received data with a
callback-method gotData().
The communication order follows this way:
One peer calls the netWorker.sendCommand()-Method, with "Object coming"
as string
and immediatly after that it does netWorker.sendObject(char[][])
On the other peers side the netWorker run-method is running as
background thread and listening for data.
And here begins my problem, because sending and receiving of the string
command with read/writeUTF
works fine so far, but when it comes to receive the object (sending
seems to work) it throws on the
receiver-side a StreamCorruptedException(invalid stream header).
My first question is, how to switch the ObjectInput/Outputstreams
correctly. Can i use one ObjectInputStream
for both receiving the command strings with readUTF() and the objects
with readObjects() ? Or do i have
to create a new Stream for each?
The second question is: The socket-object is created in another class
and this class uses a
DataInput/OutputStream on the socket to send some initial data. However
when i close these
streams after sending the data my socket is closed too and networker
hangs up. Now i leave
these streams open and close them only when my application itself exits.
Could these opened
streams lead to any trouble with the streams in my networker class?
The code of my simplified NetWorker.class is listed below,
and since i am a newbie to java programming any general comments and
tips on my code are greatly appreciated!
Please help me, i really lost my nerves on that issue...
Thanks in advance,
#jan
public class NetWorker
extends Thread
{
private Socket socket;
private boolean stoprequested;
private char[][] gameGrid;
private NetWorkerListener workerListener;
private ObjectInputStream ois;
private ObjectOutputStream oos;
public NetWorker(Socket socket, NetWorkerListener listener)
{
this.workerListener = listener;
stoprequested = false;
this.socket = socket;
try
{
oos = new ObjectOutputStream(socket.getOutputStream());
}
catch (Exception e)
{
//do something
}
}
public void sendCommand(String command)
{
try
{
if ((socket != null) && (oos != null))
{
oos.writeUTF(command);
oos.flush();
}
}
catch (Exception e)
{
// do something
}
}
public void sendObject(Object object)
{
try
{
oos.writeObject(object);
oos.flush();
}
catch (IOException e)
{
// do something
}
}
public void run() // the receiver-thread
{
try
{
ois = new ObjectInputStream(socket.getInputStream());
while (!stoprequested)
{
if ((socket != null) && (dataInputStream != null))
{
String command = ois.readUTF();
if (command.equals("POSITIONS"))
{
gameGrid = (char [] []) ois.readObject();
if(this.workerListener != null)
{
this.workerListener.gotData(command,hisGrid);
// return result to main-class
}
}
}
}
catch (Exception e)
{
// do something
}
}// end of method
}// end of class
over a network socket. Additionally i use a simple home-brew
communication-protocol
based on text messages.
1.) My object is a char[] [], representing the grid of a game.
I assume it must be serializable by default.
2) I have got a NetWorker class, which implements the run method for
receiving
data running in a separate thread. Furthermore the class has two more
methods,
one for sending text commands, and one for sending objects.
In the run-method i open up an ObjectInputstream
on my socket to listen first for a text-command with readUTF().
When it receives a command called "Object coming" it should switch the
ObjectInputStream to readObject(). The constructor of the
netWorker-class
requires a socket-object and a NetWorkerListener object which is my
main-class that implements
that listener-interface to bubble up the received data with a
callback-method gotData().
The communication order follows this way:
One peer calls the netWorker.sendCommand()-Method, with "Object coming"
as string
and immediatly after that it does netWorker.sendObject(char[][])
On the other peers side the netWorker run-method is running as
background thread and listening for data.
And here begins my problem, because sending and receiving of the string
command with read/writeUTF
works fine so far, but when it comes to receive the object (sending
seems to work) it throws on the
receiver-side a StreamCorruptedException(invalid stream header).
My first question is, how to switch the ObjectInput/Outputstreams
correctly. Can i use one ObjectInputStream
for both receiving the command strings with readUTF() and the objects
with readObjects() ? Or do i have
to create a new Stream for each?
The second question is: The socket-object is created in another class
and this class uses a
DataInput/OutputStream on the socket to send some initial data. However
when i close these
streams after sending the data my socket is closed too and networker
hangs up. Now i leave
these streams open and close them only when my application itself exits.
Could these opened
streams lead to any trouble with the streams in my networker class?
The code of my simplified NetWorker.class is listed below,
and since i am a newbie to java programming any general comments and
tips on my code are greatly appreciated!
Please help me, i really lost my nerves on that issue...
Thanks in advance,
#jan
public class NetWorker
extends Thread
{
private Socket socket;
private boolean stoprequested;
private char[][] gameGrid;
private NetWorkerListener workerListener;
private ObjectInputStream ois;
private ObjectOutputStream oos;
public NetWorker(Socket socket, NetWorkerListener listener)
{
this.workerListener = listener;
stoprequested = false;
this.socket = socket;
try
{
oos = new ObjectOutputStream(socket.getOutputStream());
}
catch (Exception e)
{
//do something
}
}
public void sendCommand(String command)
{
try
{
if ((socket != null) && (oos != null))
{
oos.writeUTF(command);
oos.flush();
}
}
catch (Exception e)
{
// do something
}
}
public void sendObject(Object object)
{
try
{
oos.writeObject(object);
oos.flush();
}
catch (IOException e)
{
// do something
}
}
public void run() // the receiver-thread
{
try
{
ois = new ObjectInputStream(socket.getInputStream());
while (!stoprequested)
{
if ((socket != null) && (dataInputStream != null))
{
String command = ois.readUTF();
if (command.equals("POSITIONS"))
{
gameGrid = (char [] []) ois.readObject();
if(this.workerListener != null)
{
this.workerListener.gotData(command,hisGrid);
// return result to main-class
}
}
}
}
catch (Exception e)
{
// do something
}
}// end of method
}// end of class