客户端服务器;客户端代码完成后,服务器抛出EOFException

时间:2014-03-01 00:15:37

标签: java sockets client

我正在尝试设置一个简单的客户端/服务器模型,通过DataInput/OutputStream发送对象。我的客户端代码是:

public static void main(String[] args) {
    final String HOST_NAME = "localhost"; 
    final int PORT_NUMBER = 9090;

    Card card = new Card(0, 0, 0, 0);

    try {
        Socket socket = new Socket(HOST_NAME, PORT_NUMBER);
        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());

        output.writeObject(card);
        card = new Card(1, 1, 1, 1);
        output.writeObject(card);
        output.writeObject(null);

        output.close();
        input.close();
        socket.close();
    } catch (UnknownHostException e) {
        System.err.println("Can not recognize: " + HOST_NAME);
    } catch (IOException e) {
        System.err.println("Bad port number: " + PORT_NUMBER);
    }
}

在服务器端,我尝试了几种代码变体,目前的代码如下:

static boolean listening = true;

public static void main(String args[]) throws IOException {
    ServerSocket serverSocket = new ServerSocket(9090);
    while (listening) {
        Socket socket = serverSocket.accept();
        try {
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

            while ((card = (Card) input.readObject()) != null) {
                for (int feature : card.getFeatures()) {
                    System.out.println(feature + " ");
                }
            }

            output.close();
            input.close();
            socket.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这是我想要的简化版本。我希望服务器继续侦听新的Card对象并打印它们的功能,直到它获得一个null对象。但是,当我运行它时会发生的情况是打印第一张卡的功能然后我立即在服务器端获得EOFException。

我尝试了上述的不同变体,包括使用finally来突破while,但在每种情况下我都没有通过打印第一张卡片。在客户端关闭套接字之前,我如何保证服务器将继续收听和接收卡?

1 个答案:

答案 0 :(得分:1)

while ((card = (Card) input.readObject()) != null) {

除非您计划给自己发送一个null来终止此循环,否则这不是一种有效的方式来阅读ObjectInputStream. readObject()方法没有&#39 ; t在流的末尾返回null:它抛出EOFException.所以,你必须抓住它。所以循环条件应该是while (true),并且readObject()调用需要在循环内部。然后你要么必须

try
{
    card = (Card)input.readObject();
    // ...
}
catch (EOFException)
{
    break;
}

在循环内部,或者在内部使用catch (EOFException)的try / catch块,现在不需要break;