Reputation: 936
i have this client/server application, and the client application sometimes completely freezes when i try send object via sockets
public Client client = new Client();
petriNetList = client.query(client.actionLoadPetriNetList, MainWindow.loginUsername);
here is the code of the client
public class Client {
public static Socket kkSocket = null;
public static PrintWriter out = null;
public static BufferedReader in = null;
public static BufferedReader stdIn = null;
public static OutputStream outputStream = null ;
public static ObjectOutputStream objectOutputStream = null ;
public static InputStream inputStream = null ;
public static ObjectInputStream objectInputStream = null ;
public String actionSavePetriNet = "SAVE PETRI NET START";
/*
* Save petri net to server
*
* @param action identifies query
* @param petriName name of the petri net
* @param username username
* @param xml content of the petri net
*
* @return int response form server
*/
public int query (String action,String petriName,String username,String xml) throws IOException {
int size ;
int result = 0;
connect();
if (action.equals(actionSavePetriNet)) {
out.println(action); // save petri net
out.println(petriName); //petri net name
out.println(username); //username
System.out.println("(Client:)" + xml);
objectOutputStream.writeObject(xml); //send object over the network
System.out.println("Dostali sme sa sem ?");
result = Integer.parseInt(in.readLine()); //read response from server
}
disconnect();
return result;
}
/*
* connect to server
* TODO: ADD hostname and port as parameter
*/
public static void connect() throws IOException {
try {
kkSocket = new Socket("osiris-PC", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
outputStream = kkSocket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputStream = kkSocket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
}
/*
* Disconnect from server
* close all input/output streams
*
*/
public static void disconnect() throws IOException {
out.close();
in.close();
stdIn.close();
objectOutputStream.close();
outputStream.close();
objectInputStream.close();
inputStream.close();
kkSocket.close();
}
}
and this is the code of server
public class PetriServer {
public static Protocol kkp = new Protocol();
public static InputStream inputStream = null ;
public static ObjectInputStream objectInputStream = null ;
public static OutputStream outputStream = null ;
public static ObjectOutputStream objectOutputStream = null ;
public static void main(String[] args) throws IOException, ClassNotFoundException {
kkp.loadUsers();
while(true) {
ServerSocket serverSocket = null;
inputStream = null ;
objectInputStream = null ;
outputStream = null ;
objectOutputStream = null ;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
inputStream = clientSocket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
outputStream = clientSocket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
inputLine = in.readLine();
String inputLine;
if (inputLine.equals("SAVE PETRI NET START")) {
String petriName;
String username;
String xml ;
String input;
int result;
int size ;
petriName = in.readLine(); //read petri name
System.out.println("(Server): prijali sme poziadavok na ulozenie " + petriName );
username = in.readLine(); //read username
System.out.println("(Server): poziadavok ide od usera: " + username);
while(true) {
//this is the line where is occasionally freezes
xml = (String)objectInputStream.readObject(); //read object over the network
if (!xml.isEmpty()) break;
}
System.out.println("(Server):" + xml);
result = kkp.savePetrinet(username, petriName,xml); //save it to the file
out.println(result);
}
out.close();
in.close();
objectInputStream.close();
inputStream.close();
objectOutputStream.close();
outputStream.close();
clientSocket.close();
serverSocket.close();
}
}
}
Does anybody know what can be problem ? cheers.
Upvotes: 1
Views: 1433
Reputation: 2115
You have the Socket InputStream on the server attached to two different inputs, ObjectInputStream
and BufferedReader
. InputStreams
are not intended to be used this way, and doing so can cause a lot of problems. BufferedReaders, by their nature, are going to be pulling more data off the InputStream
than you are actually reading. If they happen to buffer data that makes up an object, then your subsequent attempt to read the object off the ObjectInputStream
will block, because the data has already been removed.
You need to pick one method or the other to read data. If you need to be able to read both Strings and Objects off the Socket, then you will have to go to a byte-oriented mode of operation where you read the bytes off into a byte array, then process the byte array yourself to insure that you don't loose any data.
Edit based on @Dunes comment below
Seems your best bet is to stick entirely with ObjectInputStream
and make use of its other methods that allow you to read arbitrary primitive types from the stream. And, if you don't mind the deprecated call, it even has a readLine
method.
Upvotes: 1