我有一个 Java 服务器应用程序,它包含一个 Student 对象列表(实现可序列化)。客户端应用程序发送一条消息,其中包含要获取的 Student 对象的整数索引。然后将选中的Student发送给客户端,客户端修改其值并发回。然而,应用程序在某些时候卡住,这可能是我在下面的代码中强调的行的问题。
服务器:
public class Server {
public static void main(String[] arg) {
ArrayList <Student> studentList = new ArrayList <Student> ();
studentList.add(new Student(170435, "justyna", "kaluzka", new ArrayList <Float>()));
studentList.add(new Student(170438, "michal", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170436, "marek", "polewczyk", new ArrayList <Float>()));
studentList.add(new Student(170439, "jakub", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170430, "anna", "majchrzak", new ArrayList <Float>()));
studentList.add(new Student(170425, "krzysztof", "krawczyk", new ArrayList <Float>()));
studentList.add(new Student(170445, "adam", "szydlowski", new ArrayList <Float>()));
studentList.add(new Student(170415, "karol", "chodkiewicz", new ArrayList <Float>()));
studentList.add(new Student(170465, "artur", "schopenhauer", new ArrayList <Float>()));
ServerSocket socketConnection = null;
ObjectInputStream serverInputStream = null;
ObjectOutputStream serverOutputStream = null;
try {
socketConnection = new ServerSocket(11111);
System.out.println("Server Waiting");
Socket pipe = socketConnection.accept();
serverOutputStream = new ObjectOutputStream( pipe.getOutputStream());
serverInputStream = new ObjectInputStream( pipe.getInputStream());
int index = serverInputStream.readInt();
System.out.println(index);
// HERE'S WHEN THE PROBLEM STARTS
serverOutputStream.writeObject(studentList.get(index));
Student student = (Student) serverInputStream.readObject();
System.out.println(student.toString());
} catch (IOException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
serverInputStream.close();
serverOutputStream.close();
socketConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端:
public class Client {
public static void main(String[] arg) {
Student student = null;
Socket socketConnection = null;
ObjectOutputStream clientOutputStream = null;
ObjectInputStream clientInputStream = null;
try {
socketConnection = new Socket("127.0.0.1", 11111);
clientOutputStream = new ObjectOutputStream(socketConnection.getOutputStream());
clientInputStream = new ObjectInputStream(socketConnection.getInputStream());
clientOutputStream.writeInt(0);
student = (Student) clientInputStream.readObject();
student.setFamilyName("Konopnicka");
clientOutputStream.writeObject(student);
} catch (Exception e) {
System.out.println(e);
} finally {
try {
clientOutputStream.close();
clientInputStream.close();
socketConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
我对客户端-服务器套接字的了解很模糊,所以这很可能是一个简单的错误。有什么想法吗?
编辑: 学生类
public class Student implements Serializable {
private static final long serialVersionUID = -5169551431906499332L;
private int indexNumber;
private String name;
private String familyName;
private ArrayList<Float> marks;
private float average;
public Student(int indexNumber, String name, String familyName,
ArrayList<Float> marks) {
this.indexNumber = indexNumber;
this.name = name;
this.familyName = familyName;
this.marks = marks;
this.average = 0;
generateMarks();
calculateAverage();
}
public int getIndexNumber() {
return indexNumber;
}
public void setIndexNumber(int indexNumber) {
this.indexNumber = indexNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public float getAverage() {
return average;
}
public void setAverage(float average) {
this.average = average;
}
/**
* Calculates average of all Student's marks.
*/
public void calculateAverage() {
float sum = 0;
for (int i = 0; i < marks.size(); i++) {
sum += marks.get(i);
}
this.average = sum / marks.size();
}
/**
* Generates a random set of marks for the student.
*/
public void generateMarks() {
for (int i = 0; i < 10; i++) {
addMark(new Random().nextFloat() * 5);
}
}
/**
* Mark getter
*
* @return String representation of marks
*/
public String getMarks() {
String marksstr = "";
for (int i = 0; i < marks.size(); i++) {
marksstr += marks.get(i).toString() + " ";
}
return marksstr;
}
/**
* Adds a mark to the list.
*
* @param mark
*/
public void addMark(float mark) {
marks.add(mark);
}
@Override
public String toString() {
return "Index number:" + indexNumber + "\tName:" + name
+ "\tFamily name:" + familyName + "\t\tAverage:" + getAverage()
+ "\n";
}
}
最佳答案
在服务器上的 ObjectInputSteam
之前初始化您的 ObjectOutputStream
。
当您初始化ObjectInputStream
时,它会等待“ header ”数据。您的服务器正在等待该 header 数据。您需要首先初始化您的ObjectOutputStream
(发送 header 数据),然后初始化您的ObjectInputStream
。
您可以在here中找到更多相关信息。
<小时/>在写入 int 后,您必须刷新您的 ObjectOutputStream
。当您将数据写入流时,它会被写入缓冲区。仅当流的缓冲区已满时,才会发送该缓冲区中的数据。 int 不会填充它,因此您必须 flush()
它来手动从缓冲区发送数据。
关于java - Java 中的客户端-服务器应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27710676/