This question already has answers here:
ObjectInputStream/ObjectOutputStream work not right
(3 answers)
Closed 7 years ago.
I have this server/client model for a game but it keeps getting stuck at the ObjectInputStream initialization.
Here is the code for the client's start method:
public void start(){
try {
Socket s = new Socket("127.0.0.1", 24680);
Thread.sleep(1000);
ois = new ObjectInputStream(s.getInputStream()); // stuck here
oos = new ObjectOutputStream(s.getOutputStream());
startGame();
} catch (Exception e) {
e.printStackTrace();
}
}
}
here is the server code:
try {
InputStream fis = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(fis);
while (true) {
ArrayList < Dot > lists = (ArrayList < Dot > ) ois.readObject();
for (Socket s: sockets) {
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(lists);
}
}
} catch (Exception e) {
e.printStackTrace();
}
Thanks in advance!
You need to construct the ObjectOutputStream before the ObjectInputStream at at least one end, preferably both to avoid accidents. Otherwise new ObjectInputStream() blocks trying to read the stream header which hasn't been written yet by the peer's new ObjectOutputStream(), because he also is blocked in new ObjectInputStream().
Other notes:
You must use the same object streams for the life of the socket, at both ends, unlike your current code. The reason is the same: the stream header. If you keep creating new ObjectOutputStreams you will keep writing new stream headers, which the peer won't expect or understand.
Remove the sleep(). There is no need for sleeps in networking code. They are just literally a waste of time. Cargo-cult programming.
Related
I have a Problem with the ObjectInputStream. I wanna send Objects through this, but the program stops at the point where i want to initialize the ObjectInputStream. I already searched for answered and I found that the ObjectOutputstream needs to be open before you can initialize an ObjectInputStream. But this is defenitely done there.
Piece of code of my Client Class:
socket = new Socket(InetAddress.getByName(server).getHostAddress(), 13340);
messages = new Scanner(socket.getInputStream());
p = new PrintStream(socket.getOutputStream());
ObjectOutputStream o = new ObjectOutputStream(socket.getOutputStream());
p.println("addServerContent");
o.flush();
System.out.println("1");
o.writeObject(String.valueOf(index));
o.writeObject(s);
And heres the part of the server:
}else if(what.equals("addServerContent")){
ObjectInputStream i = null;
try{
i = new ObjectInputStream(s.getInputStream());
}catch(IOException e){}
while(GxMS2.ListUsed){
try {
Thread.sleep(10);
} catch (InterruptedException ex) {}
}
try{
System.out.println("1");
int index = Integer.parseInt((String)i.readObject());
ServerContent sc = (ServerContent)i.readObject();
At the server it doesn´t even reach the "1" mark.
Why isn´t it working?
Thank you
You cannot combine a character stream with an object stream so its either that you wrap the OutputStream with a PrintWriter or with an ObjectOutputStream but not both.
This is my code. When I run this, I get up to "Three and a Half" printed. (The prints are added for debugging since I don't know any other way.) After that, the execution hangs. No exceptions, no prompts, nothing. So what is wrong with my object creation? Each and every tutorial I see online has the same code, but mine won't work.
public class Connection {
Socket socket;
ObjectInputStream iStream;
ObjectOutput outputStream;
public Connection(Socket s) {
try {
System.out.println("One");
socket = s;
System.out.println("Two");
outputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
System.out.println("Three");
InputStream is = socket.getInputStream();
System.out.println("Three and a Half");
iStream = new ObjectInputStream(is);
System.out.println("Four");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks in advance.
It's in the Javadoc:
A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
So the new ObjectInputStream is hanging because it's waiting on input. You need to create an ObjectOutputStream and send data through the socket.
I'm doing my own server in Java. I need to do one socket connection and receive a lot of object from client. I did it, it works, but I don`t know if this is the best(fastest) solution. Here is example of my code:
try {
serverSocket=new ServerSocket(18234, 1000);
} catch (IOException e) {
System.out.print("Server failed..");
e.printStackTrace();
}
Object x;
ObjectInputStream ois;
System.out.println("Waiting for connection...");
Socket connection= serverSocket.accept();
System.out.println("Connection received from " + connection.getInetAddress().getHostName());
while(true){
ois = new ObjectInputStream(connection.getInputStream());
x=ois.readObject();
System.out.println(x.getString());
if(x.getString().equals("END")) break;
}
Problem is, that when I try receive new object, all time I must do new ObjectInputStream.. Is this solution correct? I must do really fast server and all time doing new ObjectInputStream is too expensive in my opinion.
Use the same ObjectOutputStream and ObjectInputStream for the life of the socket, at both ends. Your statement about being obliged to use a new one each object is incorrect.
I am currently not receiving the last object from my object stream until another set of data is sent from the server. The objects sent have either a 1,2 or 3 int to state whether they are the first middle or last packets. I have sent these objects to an array and analysed this in the debugger, it shows that the last packet does not come through until the first one is sent again.
This is the server code:
public void telleveryone(Object message){
Iterator it = clientOutputStream.iterator();
while(it.hasNext()){
try{
ObjectOutputStream everyone = (ObjectOutputStream)it.next();
everyone.writeObject(message);
everyone.flush();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This is the receiving code on the client:
public void run() {
try{
sock = new Socket("10.42.34.46", 1337);
InputStream is = sock.getInputStream();
ois = new ObjectInputStream(new BufferedInputStream(is));
OutputStream os = sock.getOutputStream();
oops = new ObjectOutputStream(os);
while(true){
serverDraw = (com.DrawTastic.Drawring) ois.readObject();
test.add(serverDraw);
}
}catch(IOException ex){
ex.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need to flush the header:
callers may wish to flush the stream immediately to ensure that
constructors for receiving ObjectInputStreams will not block when
reading the header
oops = new ObjectOutputStream(os);
oops.flush();
I didn't read over the code thoroughly, but I've run into this problem with Python. I noticed a lot of my commands to the server were not executing until my program pinged the server again. My solution was to ensure there was a newline at the end of each command to the server, or you could flush the buffer.
I am writing server-client application. Client sends some sort of data via different streams to the server. Once I place streams like this in the main method the program does nothing; no exception just empty console:
try {
socket = new Socket("localhost", 4050);
din = new DataInputStream(socket.getInputStream());
oin = new ObjectInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
System.out.println("Exception: the host is unknown");
} catch (IOException e) {
System.out.println("I/O exception thrown by socket");
}
Once I remove this stream oin = new ObjectInputStream(socket.getInputStream()); from that part of main method the program throws EOFException or connection reset exception.
What is so special in the above code that the program does nothing and throws no exceptions?
Once you place the mentioned stream in to a separate method
private static MessageObject readObject(){
MessageObject mo = null;
try{
oin = new ObjectInputStream(socket.getInputStream());
mo = (MessageObject)oin.readObject();
}
catch(IOException e){
System.err.println(e.getCause());
}
catch(ClassNotFoundException e){
System.err.println(e.getCause());
}
return mo;
}
It throws this exception:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readBoolean(Unknown Source)
at Server.main(Server.java:77)
On the server it is on the if branch:
if (din.readBoolean()) {
ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
MessageObject o = (MessageObject)oin.readObject();
// server saves the whole thing
MessageDB.add(o);
}
I can't place here all my code, it is my assignment.
ooops, sorry people, the mistake has been found. Some logical mistake, the server was expecting some input,but the client was refusing to send it.
You are making several mistakes here.
You are using multiple streams over the same socket. Don't do that, they will only confuse each other. As you need object I/O, just use an ObjectInputStream and ObjectOutputStream for everything.
Incorrect construction order. You must construct the ObjectOutputStream before the ObjectInputStream, at both ends.
You are using streams with different lifetimes. You haven't hit the problem yet but eventually this will lead to a StreamCorruptedException. Use the same ObjectInputStream and ObjectOutputStream for the life of the Socket, at both ends.
You probably also need to read the Javadoc for ObjectOutputStream.reset() and .writeUnshared() to understand what they do, and why you might need to call one or the other of them.