Reputation: 8487
How do I handle the ObjectOutputStream
and ObjectInputStream
so that the Server
instance correctly logs the received Object
. Currently, it never gets that far. Each time the client runs, the server "waits for data", but never seems to actually receive it.
server:
package net.bounceme.dur.driver;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
private final RecordQueue recordsQueue = new RecordQueue();
public static void main(String[] args) {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
while (true) {
try {
new Server().inOut(portNumber);
} catch (java.net.SocketException se) {
Logger.getLogger(Server.class.getName()).log(Level.FINE, "spammy", se);
} catch (IOException ioe) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ioe);
} catch (ClassNotFoundException cnf) {
Logger.getLogger(Server.class.getName()).log(Level.INFO, null, cnf);
}
}
}
public void inOut(int portNumber) throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket socket = serverSocket.accept();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
log.info("...connected...waiting for data...");
MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
objectOutputStream.writeObject(recordFromClient);
objectOutputStream.flush();
objectInputStream.close();
objectOutputStream.close();
log.info(recordFromClient.toString());//never logs
System.out.println("never gets here");
}
}
Each time the client runs, the server waits for data, but, at least according to the output below, never receives it.
thufir@dur:~$
thufir@dur:~$ java -jar NetBeansProjects/Server/dist/Server.jar
Jun 29, 2014 9:28:45 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...
Jun 29, 2014 9:28:46 PM net.bounceme.dur.driver.Server inOut
INFO: ...connected...waiting for data...
client code:
package net.bounceme.dur.driver;
import java.net.*;
import java.io.*;
import java.util.Properties;
import java.util.logging.Logger;
public class Client {
private static final Logger log = Logger.getLogger(Client.class.getName());
public void put(String server, int portNumber, Socket socket, ObjectOutputStream objectOutputStream) throws IOException, ClassNotFoundException {
socket = new Socket(server, portNumber);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
MyRecord record = new MyRecord(1, "foo");
objectOutputStream.writeObject(record);
objectOutputStream.flush();
objectOutputStream.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
String server = (props.getProperty("server"));
Socket socket = null;
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
new Client().put(server, portNumber, socket, objectOutputStream);
}
}
Upvotes: 0
Views: 160
Reputation: 31290
Client and Server must agree with each other not only about how they send data but also when to close a socket. A unilateral close of a socket will close the connection and thwart the reception even of data that has already been sent. And I think that's what's happening here.
Client code:
objectOutputStream.writeObject(record);
objectOutputStream.flush();
objectOutputStream.close();
This is executed without interruption and so the socket is closed as soon as the last byte has been sent on the wire. Thus, the server's reply cannot be sent.
Server code:
MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
objectOutputStream.writeObject(recordFromClient);
Clearly, reception happens a little later than sending, and so the server blocks.
Keep the socket open from both sides until the client has received; then he may close the socket. The server should see an end-of-file when trying to read again, and can close accordingly. (More elaborate handshaking is possible, of course.)
Later
To corroberate, simply add a Thread.sleep(2000); between Client's flush and close - and the Server will indeed "get here".
Upvotes: 2