Java 客户端-服务器应用程序中的 EOFException
EOFException in a Java client-server app
我正在开发一个简单的客户端-服务器时钟,它将当前时间传输到由时钟服务器应用程序托管的所有客户端。有一个定时事件(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());
}
}
您需要在 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();
}
您的服务器将日期写入流一次,然后关闭。因此,客户端在第一次读取后得到 EOFException。
我正在开发一个简单的客户端-服务器时钟,它将当前时间传输到由时钟服务器应用程序托管的所有客户端。有一个定时事件(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());
}
}
您需要在 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();
}
您的服务器将日期写入流一次,然后关闭。因此,客户端在第一次读取后得到 EOFException。