Client-server chat system Small

It contains the knowledge points:

  • Socket applications
  • Understanding of multi-threaded
  • try-catch of practice
  • Create a class to find out when the class is internal, external classes or anonymous classes
  • A preliminary understanding of the steps debugger.

In order to increase functionality:

  1. Chat 0.1 version produces a window
  2. Chat 0.2 version of the preliminary layout window
  3. Chat 0.3 version adds the window closing event
  4. Chat 0.4 version added TextField event processing
  5. Chat 0.5 version adds ChatServer
  6. Chat 0.6 version of Client connect to server
  7. Chat 0.7 version of the client to the server sends a message
  8. Chat 0.8 version fixes the previous version of the problem, the client may send multiple statements
  9. Chat 0.9 release fixes a bug version
  10. Chat 1.0 version even on multiple clients
  11. Chat 1.1 version of the server-side forwarding
  12. Chat 1.2 version of the client receives
  13. The final version of the amendment Chat 1.3

Chat experience

  • To understand the importance of iterative version of the program, no one will be able to write any program is perfect to add a new feature in each iteration.
  • Save the code at any time, Ctrl + S
  • Do not throw an exception is encountered directly, not afraid of difficulties, thoughtful, abnormal abnormal resolved with try-catch statement, exceptions may be mined after each thrown.
  • Like how to write? Class is written inside or outside the class, or anonymous class? Specifically to see what this class do
  • The correct code is 100 lines, 300 lines of code perfect. `

Server-side code:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import java.util.*;

public class ChatServer {
	boolean started = false;// 成员变量
	ServerSocket ss = null;

	List<Client> clients = new ArrayList<Client>();

	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) {// 无限接受客户端连接进来
				boolean bConnected = false;
				Socket s = ss.accept();
				Client c = new Client(s);
				System.out.println("a client connected!");
				new Thread(c).start();
				clients.add(c);
//				dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	class Client implements Runnable {
		private Socket s;
		private DataInputStream dis = null;
		private DataOutputStream dos = null;
		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 (dos != null)
						dos.close();
					if (s != null) {
						s.close();
						s = null;
					}
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

}

Client code:


```java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.*;
import java.io.*;

public class ChatClient extends Frame {
	Socket s = null;
	DataOutputStream dos = null;
	DataInputStream dis = null;
	private boolean bConnected = false;

	TextField tfTxt = new TextField();// 输入框
	TextArea taContent = new TextArea();// 显示框

	Thread tRecv = new Thread(new RecvThread());

	public static void main(String[] args) {
		new ChatClient().launchFrame();
	}

	public void launchFrame() {
		setLocation(400, 300);// 设置窗口的位置
		this.setSize(300, 300);// 设置窗口的大小
		add(tfTxt, BorderLayout.SOUTH);// 把输入框放到南边
		add(taContent, BorderLayout.NORTH);// 显示框放到北边
		pack();
		this.addWindowListener(new WindowAdapter() {// 窗口关闭监听按钮

			@Override
			public void windowClosing(WindowEvent e) {
				disconnect();// 关闭窗口的同时,关闭流,关闭套接字
				System.exit(0);// 退出系统
			}

		});
		tfTxt.addActionListener(new TFListener());
		setVisible(true);// 设置为可视化
		connect();// 窗口一打开就直接连接

		tRecv.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();
		}
		/*
		try {
			bConnected = false;
			tRecv.join();

		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			try {
				dos.close();
				dis.close();
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}*/
	}

	private 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();// 刷新流
				// dos.close();//关闭流
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}

	}

	public 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("退出了,再见!");
			} 
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}



Published 23 original articles · won praise 37 · views 8238

Guess you like

Origin blog.csdn.net/weixin_44861399/article/details/104225235