在线聊天(JavaSE实战项目)学习笔记

Chat0.1

搭建客户端ChatClient窗口,有两种方式:

一、继承Frame类(比较灵活)

调用Frame类中的setLocation(int x, int y)方法设置窗口位置,setSize(int width, int height)方法设置窗口大小,setVisible(true)方法将窗口显示出来

setSize(int width, int height):其实就是定义控件的大小,有两个参数,分别对应宽度和高度;

setLocation(int x, int y):将组件移到新位置,用x 和 y 参数来指定新位置的左上角

setBounds(int x, int y, int width, int height):四个参数,既定义组件的位置,也定义控件的大小; 其实它就是上面两个函数的功能的组合

import java.awt.Frame;

public class ChatClient extends Frame{

	public static void main(String[] args) {

		new ChatClient().launchFrame();
	}
	
	public void launchFrame()
	{
		setLocation(400, 300);
		setSize(300, 300);
		setVisible(true);
	}
}

二、直接使用Frame类


Chat0.2

向客户端窗口中添加文本输入框TextField和文本输入区TextArea(可以输入多行文本),使用add方法

import java.awt.*;

public class ChatClient extends Frame{

	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}
	
	public void launchFrame(){
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();//void pack() 使此窗口的大小适合其子组件的首选大小和布局。 
		setVisible(true);
	}

}

Chat0.3

添加客户端窗口关闭功能,使用窗口的 addWindowListener 方法

WindowListener是java中的接口。主要作用:
用于接收窗口事件的侦听器接口。旨在处理窗口事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象类WindowAdapter(仅重写所需的方法)。然后使用窗口的 addWindowListener 方法将从该类所创建的侦听器对象向该 Window 注册。当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给该方法。
import java.awt.*;
import java.awt.event.*;

public class ChatClient extends Frame{
	
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args){
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		setVisible(true);
	}
}

Chat0.4

向客户端中添加功能:在文本输入框TextFiled中输入内容按回车键后,内容会显示到文本输入区TextArea中

取文本内容getText()方法,设置文本内容setText()方法

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ChatClient extends Frame{
	
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args){
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
			
		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);
	}
	
	private class TFListener implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent e) {
			String s = tfTxt.getText().trim();
			taContent.setText(s);
			tfTxt.setText("");
		}
		
	}
}

Chat0.5

创建ChatSever服务端

1、使用ServerSocket创建服务端(ServerSocket对象用于监听来自客户端的Socket连接)

        ServerSocket(int port):用指定的端口port来创建一个ServerSocket。该端口应该有一个有效的端口整数值,即0~65535。

2、接收来自客户端Socket的连接请求,使用accept()方法

        ServerSocket包含一个监听来自客户端连接请求的方法,即accept()方法

        Socket accept():如果接收到一个客户端Socket的连接请求,该方法将返回一个与客户端Socket对应的Socket;否则该方法将一直处于等待状态,线程也被阻塞。

注意:服务端只有一个,客户端有多个,需使用while循环来接收多个客户端

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {
	public static void main(String[] args) {
		try{
			ServerSocket ss = new ServerSocket(8888);
			while(true) {//用于接收多个客户端
				Socket s = ss.accept();
                                System.out.println("a client connected");//用于验证客户端是否已连接成功			
			}
		}
		catch(IOException e) {
			e.printStackTrace();
		}	
	}
}

Chat0.6

ChatClient

1、在显示客户端窗口的同时,将客户端与服务端进行连接,将连接步骤封装成connect()方法

2、connect()方法

(1)创建客户端对象:客户端通常使用Socket的构造器来连接到指定的服务器

Socket(InetAddress, int port):创建连接到指定远程主机、远程端口的Socket,该构造器没有指定本地地址、本地端口,默认使用本地主机的默认IP地址,默认使用系统动态分配的端口。

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClient extends Frame{
	Socket s = null;
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}
	
	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);
		connect();
	}
	
	public void connect() {
		try {
			s = new Socket("127.0.0.1", 8888);
System.out.println("connected");
		}catch(UnknownHostException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
	
	public class TFListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			String str = tfTxt.getText().trim();
			taContent.setText(str);
			
		}
	}

}

ChatServer

接收客户端发送过来的数据

当客户端、服务端产生了对应的Socket之后,,程序无须再区分服务器端、客户端,而是通过各自的Socket通信。Socket提供了如下两个方法来获取输入流和输出流。

(1)InputStream getInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据。

(2)OutputStream getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据。

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {

	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8888);
			while(true) {
				Socket s = ss.accept();
System.out.println("a client connected");
				DataInputStream dis = new DataInputStream(s.getInputStream());
				String str = dis.readUTF();
				System.out.println(str);
				dis.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
	}

}

Chat0.7

ChatClient

将从文本输入框TextField中获取到数据发送到服务端(客户端---->服务端)

OutputStream getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据。

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;


public class ChatClient extends Frame{
	Socket s = null;
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);
		connect();
	}
	
	public void connect() {
		try {
			s = new Socket("127.0.0.1", 8888);
System.out.println("connected");
		}catch(UnknownHostException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
	
	public class TFListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			String str = tfTxt.getText().trim();
			taContent.setText(str);
			tfTxt.setText("");
			
			try {
				DataOutputStream dos = new DataOutputStream(s.getOutputStream());
				dos.writeUTF(str);
				dos.flush();
				dos.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
}

Chat0.8

ChatClient

在关闭窗口的同时关闭输出流,关闭Socket

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;


public class ChatClient extends Frame{
	Socket s = null;
	DataOutputStream dos = null;
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	
	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				disconnect();
				System.exit(0);
			}
		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);
		connect();
	}
	
	public void connect() {
		try {
			s = new Socket("127.0.0.1", 8888);
			dos = new DataOutputStream(s.getOutputStream());
System.out.println("connected");
		}catch(UnknownHostException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}
	}
	
	public void disconnect() {
		try{
			dos.close();
			s.close();
		}catch(IOException e) {
			e.printStackTrace();
		}
		
	}
	public class TFListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			String str = tfTxt.getText().trim();
			taContent.setText(str);
			tfTxt.setText("");
			
			try {
				dos.writeUTF(str);
				dos.flush();
				//dos.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}
}

ChatServer

在之前的版本中服务端不能连续读取客户端发送过来的数据。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataInputStream;

public class ChatServer {

	public static void main(String[] args) {
		boolean started = false;
		try{
			ServerSocket ss = new ServerSocket(8888);
			started = true;
			while(started) {//该while循环用于接收多个客户端
				boolean bConnected = false;
				Socket s = ss.accept();
System.out.println("a client connected");
				bConnected = true;
				DataInputStream dis = new DataInputStream(s.getInputStream());
				while(bConnected) {//该while循环可以连续读取客户端发送过来的信息
					String str = dis.readUTF();
					System.out.println(str);
				}
				
				dis.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}
		
	}

}

Chat0.9

ChatClient无改动

ChatServer

异常处理:

(1)服务器端启动后,若再次启动服务端,则会产生BindException异常。原因是服务器端启动后,端口已经被占用,无法二次启动。

(2)启动服务器端和客户端后,若关闭客户端则会发生EOFException。

产生原因:服务端读取客户端发过来的数据使用的是readUTF()方法,该方法是阻塞式方法。在客户端关闭后,服务端并不知晓,仍在等待接收数据。

在线聊天(JavaSE实战项目)学习笔记_第1张图片

在线聊天(JavaSE实战项目)学习笔记_第2张图片

通过这个API,我们可以得出以下信息:

  • 这是一个IO异常的子类,名字也是END OF FILE的缩写,当然也表示流的末尾
  • 它在表明一个信息,流已经到末尾了,而大部分做法是以特殊值的形式返回给我们,而不是抛异常

  也就是说这个异常是被主动抛出来的,而不是底层或者编译器返回给我的,就像NullPointerException或IndexOutOfBoundsException一样。

详细解释见:https://www.cnblogs.com/yiwangzhibujian/p/7107084.html

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataInputStream;

public class ChatServer {
	public static void main(String[] args) {
		boolean started = false;
		try{
			ServerSocket ss = new ServerSocket(8888);
			started = true;
			while(started) {//该while循环用于接收多个客户端
				boolean bConnected = false;
				Socket s = ss.accept();
System.out.println("a client connected");
				bConnected = true;
				DataInputStream dis = new DataInputStream(s.getInputStream());
				while(bConnected) {//该while循环可以连续读取客户端发送过来的信息
					String str = dis.readUTF();
					System.out.println(str);
				}
				dis.close();
			}
		}catch(IOException e) {
			e.printStackTrace();
		}	
	}
}

Chat1.0

启动服务器端后,若开启多个客户端窗口,则服务器端显示只能连接一个客户端,其他客户端窗口连接不上服务器,向服务器发送数据也无法显示。

原因:服务器端读取客户端发送过来的数据使用的是readUTF()方法,该方法为阻塞式方法,主方法运行后,会卡在该方法处,一直等待接收数据。这也就导致服务器端只能处理一个客户端。

处理方法:开启多线程

import java.io.*;
import java.net.*;

public class ChatServer {
	boolean started = false;
	ServerSocket ss = null;
	
	public static void main(String[] args) {
		new ChatServer().start();
	}

	public void start() {
		try {
			ss = new ServerSocket(8888);
		} catch(BindException e) {
			System.out.println("端口使用中......");
			System.out.println("请关掉相关程序,并重新运行!");
			System.exit(0);
		} catch(IOException e) {
			e.printStackTrace();
		}
		
		try {
			started = true;
			while (started) {
				Socket s = ss.accept();
				Client c = new Client(s);
				new Thread(c).start();
			}
		} catch (IOException e) {
			e.printStackTrace();	
		} finally {
			try {
				ss.close();
			} catch(IOException e1) {
				e1.printStackTrace();
			}
		}
	}
	class Client implements Runnable {
		private Socket s;
		private DataInputStream dis;
		private boolean bConnected = false;
		
		public Client(Socket s) {
			this.s = s;
			try {
				dis = new DataInputStream(s.getInputStream());
				bConnected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			System.out.println("a client connected");
			try {
				while (bConnected) {
					String str = dis.readUTF();
					System.out.println(str);
				}
			} catch(EOFException e) {
				System.out.println("Client closed");
			} catch (IOException e) {
				e.printStackTrace();	
			} finally {
				try {
					dis.close();
					s.close();
				} catch(IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
}

Chat1.1

将从某一客户端接收到的数据转发给其他客户端。

List clients = new ArrayList<>();//将线程对象存储起来,一个线程对象即代表一个客户端
while (bConnected) {
	String str = dis.readUTF();
        System.out.println(str);
	for(int i = 0; i < clients.size(); i++) {
		Client c = clients.get(i);
		c.send(str);
	}
}
将从客户端读取到的数据,通过对List集合的逐一遍历,发送给每个客户端对象。
import java.io.*;
import java.net.*;
import java.util.*;

public class ChatServer {
	ServerSocket ss = null;
	boolean started = false;
	List clients = new ArrayList<>();
	
	public static void main(String[] args) {
		new ChatServer().start();
	}
	
	public void start() {
		try {
			ss = new ServerSocket(8888);
			started = true;
		} catch(BindException e) {
			System.out.println("端口使用中");
			System.out.println("请关闭相关程序重新运行服务器");
			System.exit(0);
		} catch(IOException e) {
			e.printStackTrace();
		}
		
		try {
			while(started) {
				Socket s = ss.accept();
				System.out.println("a client connected");
				Client c = new Client(s);
				new Thread(c).start();	
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	class Client implements Runnable {
		private Socket s;
		private DataInputStream dis;
		private DataOutputStream dos;
		private boolean bConnected = false;
		public Client (Socket s) {
			this.s = s;
			try {
				dis = new DataInputStream(s.getInputStream());
				dos = new DataOutputStream(s.getOutputStream());
				bConnected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void send(String str) {
			try {
				dos.writeUTF(str);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			try {
				while (bConnected) {
					String str = dis.readUTF();
System.out.println(str);
					for(int i = 0; i < clients.size(); i++) {
						Client c = clients.get(i);
						c.send(str);
					}
				}
			} catch (EOFException e) {
				System.out.println("Client closed!");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if(dis != null) {
						dis.close();
					}
					if(s != null) {
						s.close();
					}	
					if(dos != null) {
						dos.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
}

Chat1.2

客户端接收从服务端发送过来的每个客户端的数据,并将数据显示到文本输入区TextArea中

当我们在向服务器端发送本地客户端的数据时,需要同时接收其他客户端发送过来的数据。因此需要使用多线程。

1.2异常处理:

开启多个客户端,同时进行聊天,当某一个客户端关闭后,会产生SocketException

原因:开启多个客户端后,在关闭其中某一个客户端时(主线程结束),会调用disconnect()方法,将客户端Socket关闭,而此时接收数据的线程中的输入流可能并未关闭,仍会从客户端Socket中读取数据,此时就会产生SocketException异常。

简单处理方式:直接进行捕捉,给出相应提示。

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

public class ChatClient extends Frame{
	TextField tfTxt = new TextField();
	TextArea taContent = new TextArea();
	Socket s = null;
	DataOutputStream dos = null;
	DataInputStream dis = null;
	private boolean bConnected = false;
	
	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);
		setSize(300, 300);
		add(tfTxt, BorderLayout.SOUTH);
		add(taContent, BorderLayout.NORTH);
		pack();
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				disconnect();
				System.exit(0);
			}	
		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);
		connect();
		new Thread(new RecvThread()).start();
	}
	
	public void connect() {
		try {
			s = new Socket("127.0.0.1", 8888);
			dos = new DataOutputStream(s.getOutputStream());
			dis = new DataInputStream(s.getInputStream());
			System.out.println("connected");
			bConnected = true;
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void disconnect() {
		try {
			dos.close();
			dis.close();
			s.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public class TFListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			String str = tfTxt.getText().trim();
			//taContent.setText(str);
			tfTxt.setText("");
			
			try {
				dos.writeUTF(str);
				dos.flush();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			
		}
		
	}

	private class RecvThread implements Runnable {
		public void run() {
			try {
				while(bConnected) {
					String str = dis.readUTF();
					taContent.setText(taContent.getText() + str + '\n');
				}	
			} catch(SocketException e) {
				System.out.println("退出了,bye!");
			} catch(IOException e) {
				e.printStackTrace();
			}
		}	
	}
}
Chat1.3

异常处理:

(1)同时开启多个客户端进行聊天,当其中某个客户端关闭,继续进行聊天时会产生SocketException。

在线聊天(JavaSE实战项目)学习笔记_第3张图片

产生原因:服务器端会通过Socket向每个客户端发送数据,我们将每个客户端的Socket用List集合进行存储,服务器端向每个客户端发送数据时,会通过遍历List集合逐一发送,而此时关闭的客户端的Socket仍在其中,并未从List集合中移除,因此服务器端仍然会像关闭的客户端发送数据,此时便会产生SocketException异常。

处理方式:在发送数据时直接从List集合中移除,并给出提示信息。

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatServer {
	ServerSocket ss = null;
	boolean started = false;
	List clients = new ArrayList<>();
	
	public static void main(String[] args) {
		new ChatServer().start();
	}
	
	public void start() {
		try {
			ss = new ServerSocket(8888);
			started = true;
		} catch(BindException e) {
			System.out.println("端口使用中");
			System.out.println("请关闭相关程序重新运行服务器");
			System.exit(0);
		} catch(IOException e) {
			e.printStackTrace();
		}
		
		try {
			while(started) {
				Socket s = ss.accept();
				System.out.println("a client connected");
				Client c = new Client(s);
				new Thread(c).start();
				clients.add(c);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}
	
	class Client implements Runnable {
		private Socket s;
		private DataInputStream dis;
		private DataOutputStream dos;
		private boolean bConnected = false;
		
		public Client (Socket s) {
			this.s = s;
			try {
				dis = new DataInputStream(s.getInputStream());
				dos = new DataOutputStream(s.getOutputStream());
				bConnected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void send(String str) {
			try {
				dos.writeUTF(str);
			} catch (SocketException e) {
				clients.remove(this);
				System.out.println("对方退出了!我从List里面去掉了!");
			} catch (IOException e) {
				clients.remove(this);
				System.out.println("对方退出了");
			}
		}
		
		public void run() {
			try {
				while (bConnected) {
					String str = dis.readUTF();
System.out.println(str);
					for(int i = 0; i < clients.size(); i++) {
						Client c = clients.get(i);
						c.send(str);
					}
				}
			} catch (EOFException e) {
				System.out.println("Client closed!");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if(dis != null) {
						dis.close();
					}
					if(s != null) {
						s.close();
					}	
					if(dos != null) {
						dos.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
}

注意:EOFException、SocketException均是IOException的子类

你可能感兴趣的:(在线聊天(JavaSE实战项目)学习笔记)