我编写了一个在两台计算机之间发送消息的程序。发送消息很好。但是,当我从MessageClient类调用exit()方法时,它会从ServerThread中抛出“ EOF异常”,并从ClientThread中抛出“ SocketException:套接字已关闭”。两个线程中的“ while循环”是无限的,我想在调用exit()方法时停止。我该如何解决?

主要:

package team.kha.lan_message;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
    Scanner scan;
    String cmd;
    while(true){
        System.out.print(">> ");
        scan = new Scanner(System.in);
        cmd = scan.nextLine();

        if(cmd.equals("server")){
            new MessageServer();
            scan.close();
            break;
        }
        else if(cmd.equals("client")){
            new MessageClient();
            scan.close();
            break;
        }
        else if(cmd.equals("exit")){
            scan.close();
            break;
        }
        else{
            System.out.println("Wrong Usage!");
            System.out.println("\t Usage: <server> - start [Address] [Port]");
            System.out.println("\t Usage: <client> - connect [Address] [Port]");
            System.out.println("\t                 - send [Message]");
            System.out.println("\t                 - exit\n");
            }
        }
    }
}


MessageServer:

 package team.kha.lan_message;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;


public class MessageServer {

Scanner scan;
String cmd;
String[] params;
String ipAddress;
int port;
DataInputStream din;
DataOutputStream dout;
Socket s;
ServerSocket ss;
boolean started = false;

MessageServer(){
    while(true){
        System.out.print("(server):");
        scan = new Scanner(System.in);
        cmd = scan.nextLine();

        if(!cmd.startsWith(" ")){
            params = cmd.split(" ");

            if(params[0].equals("start") && params.length == 3 && started == false){
                startServer();
            }
            else if(params[0].equals("send") && params.length >= 2 && started == true){
                sendMessage();
            }
            else if(params[0].equals("exit") && params.length == 1){
                exit();
                break;
            }
        }
    }
}

private void exit() {
    try {
        if(started == true){
            s.close();
            ss.close();
        }
        scan.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void sendMessage() {
    String msgout = "";

    for(int i = 1 ; i < params.length ;i++){
        if(i == params.length-1){
            msgout += params[i];
        }
        else{
            msgout += params[i] + " ";
        }
    }
    try {
        dout.writeUTF(msgout);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void startServer() {
    ipAddress = params[1];
    port = Integer.parseInt(params[2]);

    try {
        ss = new ServerSocket();
        ss.bind(new InetSocketAddress(ipAddress , port));
        s = ss.accept();
        din = new DataInputStream(s.getInputStream());
        dout = new DataOutputStream(s.getOutputStream());

        new ServerThread(din);

        started = true;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
    }
}


ServerThread:

package team.kha.lan_message;

import java.io.DataInputStream;
import java.io.IOException;

public class ServerThread extends Thread {

private DataInputStream din;

ServerThread(DataInputStream din){
    this.din = din;
    start();
}


@Override
public void run() {
    while(true){
        try {
            System.out.print("\n(client):"+din.readUTF()+ "\n(server):");
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
        }
    }



}


MessageClient:

package team.kha.lan_message;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class MessageClient {

Scanner scan;
String cmd;
String[] params;
String ipAddress;
int port;
DataInputStream din;
DataOutputStream dout;
Socket s;
boolean connected = false;

MessageClient(){

    while(true){
        System.out.print("(client):");
        scan = new Scanner(System.in);
        cmd = scan.nextLine();

        if(!cmd.startsWith(" ")){
            params = cmd.split(" ");

            if(params[0].equals("connect") && params.length == 3 && connected == false){
                connectServer();
            }
            else if(params[0].equals("send") && params.length >= 2 && connected == true){
                sendMessage();
            }
            else if(params[0].equals("exit") && params.length == 1){
                exit();
                break;
            }
        }
    }
}

private void exit() {
    try {
        if(connected == true){
            s.close();
        }
        scan.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void sendMessage() {
    String msgout = "";
    for(int i = 1 ; i < params.length ;i++){
        if(i == params.length-1){
            msgout += params[i];
        }
        else{
            msgout += params[i] + " ";
        }
    }
    try {
        dout.writeUTF(msgout);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void connectServer() {
    ipAddress = params[1];
    port = Integer.parseInt(params[2]);

    try {
        s = new Socket(ipAddress , port);

        din = new DataInputStream(s.getInputStream());
        dout = new DataOutputStream(s.getOutputStream());

        new ClientThread(din);
        connected = true;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
    }
}


ClientThread:

package team.kha.lan_message;

import java.io.DataInputStream;
import java.io.IOException;

public class ClientThread extends Thread{

private DataInputStream din;

ClientThread(DataInputStream din){
    this.din = din;
    start();
}


@Override
public void run() {
    while(true){
        try {
            System.out.print("\n(server):"+din.readUTF()+ "\n(client):");
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
        }
    }

}

最佳答案

没有要修复的东西。那是应该发生的。您读到流的末尾=>,您得到EOFException。只需单独捕获它,然后按break

在循环内捕获和忽略IOExceptions几乎总是不正确的。唯一不会致命的连接是SocketTimeoutException

09-28 07:40