我想停止从 Socket 中的数据输入流读取

I want to stop reading from data input stream in Socket

我编写了一个在两台计算机之间发送消息的程序。发送消息没问题。但是当我从 MessageClient class 调用 exit() 方法时,它从 ServerThread 抛出 'EOF exception' 并从 ClientThread 抛出 'SocketException: Socket Closed'。 'while loop' 在两个线程中都是无限的,我想在调用 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");
            }
        }
    }
}

消息服务器:

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

服务器线程:

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



}

消息客户端:

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

客户端线程:

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.