【问题标题】:EOFException in a Java client-server appJava 客户端-服务器应用程序中的 EOFException
【发布时间】:2015-01-03 15:05:16
【问题描述】:

我正在开发一个简单的客户端-服务器时钟,它将当前时间传输到由时钟服务器应用程序托管的所有客户端。有一个定时事件(TimerTask)定期向所有客户端发送数据。在服务器部分它工作正常,但是当客户端运行时,它只读取一次时间,即使它处于一个 while 循环中 - 它跳转到 catch 块并引发 EOFException。它很可能是由 while 循环中的 readUTF() 方法抛出的。我该如何抵消它?

public class Client {

public static void main(String[] arg) {


    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());     

        while(true){
            String date = clientInputStream.readUTF();
            clientOutputStream.flush();
            System.out.println(date);

        }

    } catch (Exception e) {
        System.out.println("The following exception has occured and was caught:");
        System.out.println(e);
    }

    finally{
        try {
            clientOutputStream.close();
            clientInputStream.close();              
            socketConnection.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}

例如,我可以将整个 try/catch/finally 块放在一个 while 循环中,然后它就可以正常工作了。但是这样我的客户端每秒都会断开连接并重新连接到服务器,这是不可接受的。有什么想法吗?

编辑 - 堆栈跟踪:

java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at task2.Client.main(Client.java:28)

编辑 - 服务器代码:

public class Server {

 public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = null;

        boolean listeningSocket = true;
        try {
            serverSocket = new ServerSocket(11111);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 11111");
        }


        while(listeningSocket){
            System.out.println("Waiting for a client to connect...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected!");
            ConnectThread ct = new ConnectThread(clientSocket);
            ct.start();
        }
        System.out.println("closed");
        serverSocket.close();       
    }

}

服务器一直在监听传入的客户端,每次它接受连接时,它都会在一个单独的线程上开始对话,由以下类定义:

public class ConnectThread extends Thread{

private Socket socket = null;
public ConnectThread(Socket socket) {
    super("ConnectThread");
    this.socket = socket;
}

@Override
public void run(){
    ObjectOutputStream serverOutputStream = null;
    ObjectInputStream serverInputStream = null;
    try {           
        serverOutputStream = new ObjectOutputStream(socket.getOutputStream());          
        serverInputStream = new ObjectInputStream(socket.getInputStream());

        ClockTask ctask = new ClockTask();
        Timer timer = new Timer();
        timer.schedule(ctask, 0, 1000);

        Thread.sleep(1000);
        serverOutputStream.writeUTF(ctask.date);
        serverOutputStream.flush();


    } catch (IOException | InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally{
        try {
            serverOutputStream.close();
            serverInputStream.close();              
            socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }       
}
}

安排定期日期更新:

public class ClockTask extends TimerTask {

public Calendar c;
public String date;

@Override
public void run() {
    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");       
    this.c = Calendar.getInstance();
    this.date = dateFormat.format(c.getTime());
}

}

【问题讨论】:

  • 堆栈跟踪在哪里?那是你的连接突然关闭了吗?
  • 不,服务器仍然保持稳定,只是客户端程序退出。
  • 可能服务器关闭了流/套接字,客户端看到了EOF。看看服务器代码?
  • 为了提高获得答案的机会和质量,请提供full but short code necessary to reproduce your problem。目前还没有服务器代码,所以我们只能猜测可能出了什么问题,以及为什么readUTF 无法读取其数据。
  • 不需要clientOutputStream.flush();或完全使用此流(除非它只是计划添加的占位符)

标签: java client server clock eofexception


【解决方案1】:

在 ConnectThread 的运行中需要一个循环 - 实际上,它会停止并关闭流。

编辑代码:

ClockTask ctask = new ClockTask();
Timer timer = new Timer();
timer.schedule(ctask, 0, 1000);
while( true ){
    Thread.sleep(1000);
    serverOutputStream.writeUTF(ctask.date);
       serverOutputStream.flush();
}

【讨论】:

  • 我什至认为 ClockTask 可以在循环之外 - 将事件安排一次就足够了,无论如何都会重复。
【解决方案2】:

您的服务器将日期写入流一次,然后关闭。因此,客户端在第一次读取后会收到 EOFException。

【讨论】:

    猜你喜欢
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    相关资源
    最近更新 更多