我有这个客户端/服务器应用程序,当我尝试通过套接字发送对象时,客户端应用程序有时会完全冻结
public Client client = new Client();
petriNetList = client.query(client.actionLoadPetriNetList, MainWindow.loginUsername);
这是客户端的代码
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();
}
}
这是服务器的代码
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();
}
}
}
有人知道会出现什么问题吗? 欢呼声。
答案 0 :(得分:1)
服务器上的Socket InputStream连接到两个不同的输入ObjectInputStream
和BufferedReader
。 InputStreams
不打算以这种方式使用,这样做会导致很多问题。 BufferedReaders,就其本质而言,将从InputStream
中提取的数据超过您实际阅读的数据。如果它们恰好缓冲构成对象的数据,那么随后尝试从ObjectInputStream
读取对象将会阻止,因为数据已被删除。
您需要选择一种方法或另一种方法来读取数据。如果你需要能够从套接字读取字符串和对象,那么你将不得不进入面向字节的操作模式,你将字节读入字节数组,然后自己处理字节数组以确保你没有丢失任何数据。
根据以下@Dunes评论进行编辑
似乎你最好的选择是完全坚持使用ObjectInputStream
并使用其他方法来允许你从流中读取任意基本类型。而且,如果你不介意弃用的电话,它甚至有一个readLine
方法。