我编写了一个在两台计算机之间发送消息的程序。发送消息很好。但是,当我从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
。