简体   繁体   English

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

[英]EOFException in a Java client-server app

I'm developing a simple client-server clock, which transmits the current time to all clients, hosted by the clock server application. 我正在开发一个简单的客户端服务器时钟,该时钟将当前时间传输到由时钟服务器应用程序托管的所有客户端。 There is a timed event (TimerTask) that sends the data periodically to all clients. 有一个定时事件(TimerTask),它定期将数据发送到所有客户端。 And at the Server part it works fine, but when the client runs, it reads the time only once, even though it's in a while loop - it jumps to the catch block and raises EOFException. 在服务器部分,它工作正常,但是当客户端运行时,即使它处于while循环中,它也只读取一次时间-跳转到catch块并引发EOFException。 It's throwny most likely by readUTF() method in the while loop. while循环中的readUTF()方法很可能会引发麻烦。 How can I counteract it? 我该如何应对?

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


}

I could, for example, put the entire try/catch/finally block in a while loop, and then it works fine. 例如,我可以将整个try / catch / finally块放入while循环中,然后工作正常。 But this way my client disconnects and reconnects to the server every single second, which is unacceptable. 但是这样,我的客户端每隔一秒钟就会断开连接并重新连接到服务器,这是不可接受的。 Any ideas? 有任何想法吗?

EDIT - stacktrace: 编辑-stacktrace:

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)

EDIT - server code: 编辑-服务器代码:

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

}

Server keeps listening for incoming clients, and every time it accepts a connection, it starts conversation on a separate thread, defined by the following class: 服务器一直在监听传入的客户端,并且每次接受连接时,它都会在由以下类定义的单独线程上启动对话:

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

which schedules periodic date update: 计划定期更新日期:

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

}

You need a loop in the run of ConnectThread - as it is, it stops and the stream is closed. 在ConnectThread运行时需要一个循环-就这样,它停止并且流关闭。

Edit the Code: 编辑代码:

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

Your server writes the date once to the stream and then closes. 您的服务器将日期一次写入流中,然后关闭。 hence, the client gets and EOFException after the first read. 因此,客户端在第一次读取后获取和EOFException。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM