java - Java 中的客户端-服务器应用程序

标签 java sockets serialization client server

我有一个 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/

相关文章:

java - 我的字符串排列算法不起作用

java - 尝试返回 2 个 boolean 值 Java

Java: JSONObject.toString() - 在冒号 (":"-> ": "之后添加额外的空间)

java - 如何使用 Web 服务传递对象等复杂类型?

java - 在Java中增加ArrayList中ArrayList的大小

c++ - 使用本地 ipv6 套接字将 UDP 发送到本地 ipv4 地址

facebook - 通过 Nodejs 的 TLS Socket 连接

C - recvfrom 和信号

json - 为什么要在 JSON 中使用字符串来表示十进制数

django - Rest Framework 序列化程序字段只读不起作用