网络编程之简单的多人聊天程序

本文介绍了一个简单的TCP聊天服务器和客户端的实现方法,通过Java编程语言创建了一个能够支持多客户端连接并进行消息群发的聊天系统。该系统包括服务器端和客户端两个部分,服务器端负责接收客户端连接请求及消息分发,客户端则用于发送和接收消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务器端

package net;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;

import javax.swing.*;
//服务器端程序
public class TCPServer extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private ServerSocket ss = null;
	private boolean bStart = false;
	
	private JTextArea taContent = new JTextArea();
	
	private int index = 0;
	
	List<Client> clients = new ArrayList<Client>();
	
	public void launchFrame() {
		//Container con = this.getContentPane();
		taContent.setEditable(false);
		taContent.setBackground(Color.DARK_GRAY);
		taContent.setForeground(Color.YELLOW);
		this.add(taContent);
		this.setSize(300, 350);
		this.setLocation(400, 200);
		this.setTitle("TCP Server");
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		tcpMonitor();//调用监听器方法
	}
	//监听器方法
	public void tcpMonitor() {
		try {
			ss = new ServerSocket(8888);
			bStart = true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			while (bStart) {
				index++;
				Socket s = ss.accept();
				Client c = new Client(s);
				clients.add(c);
				
				taContent.append(s.getInetAddress().getHostAddress()
						+ " connected " + index + " clients\n");
				new Thread(c).start();
				
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
		
	}
	
	public static void main(String args[]) {
		TCPServer ts = new TCPServer();
		ts.launchFrame();
	}
	
	private class Client implements Runnable {
		DataInputStream dis = null;
		DataOutputStream dos = null;
		
		Socket s = null;
		boolean bStart = false;
		
		Client(Socket s) {
			this.s = s;
			try {
				dis = new DataInputStream(s.getInputStream());
				dos = new DataOutputStream(s.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			bStart = true;
		}
		//分发信息给每个客户端
		public void sendToEveryClient(String str) {
			try {
				dos.writeUTF(str);
				dos.flush();
				
			} catch (IOException e) {
				index--;
				clients.remove(this);
				taContent.append(s.getInetAddress().getHostAddress()
						+ " exited " + index + " clients\n");
				System.out.println("对方退出了!我从List里面去掉了!");
			}
		}
		
		public void run() {
			try {
				while (bStart) {
					String str = dis.readUTF();
					System.out.println(str);
					for (int i = 0; i < clients.size(); i++) {
						Client c = clients.get(i);
						c.sendToEveryClient(str);//群发消息当然要在循环 环境里
					}
				}
			} catch (EOFException e) {
				clients.remove(this);
				taContent.append(s.getInetAddress().getHostAddress()
						+ " exited " + clients.size() + " clients\n");
				System.out.println("client closed");
			} catch (SocketException e) {
				System.out.println("client closed");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (s != null)
						s.close();
					if (dis != null)
						dis.close();
					if (dos != null)
						dos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
}

客户端

package net;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import javax.swing.*;

public class TCPClient extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	TextArea taContent = new TextArea();
	JTextField tfTxt = new JTextField(20);
	
	JButton send = new JButton("发送");
	JButton connect = new JButton("连接");
	JButton clear = new JButton("清空");
	
	boolean live = false;
	JPanel p1 = new JPanel();
	JPanel p2 = new JPanel();
	
	Socket s = null;
	DataOutputStream dos = null;
	DataInputStream dis = null;
	
	boolean bConnected = false;
	
	Thread t = new Thread(new RecToServer());
	
	public void launchFrame() {
		
		taContent.setEditable(false);
		
		p2.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 5));
		p2.add(send);
		p2.add(connect);
		p2.add(clear);
		
		Container con = this.getContentPane();
		
		con.add(taContent, "North");
		con.add(tfTxt, "Center");
		con.add(p2, "South");
		
		this.setSize(300, 350);
		this.setLocation(400, 200);
		this.setTitle("Chat Client");
		
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		connect.addActionListener(new Connect());
		send.addActionListener(new SendMsg());
		clear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				taContent.setText("");
			}
		});
	}
	
	public void connectToServer() {
		try {
			
			s = new Socket("127.0.0.1", 8888);
			dos = new DataOutputStream(s.getOutputStream());
			dis = new DataInputStream(s.getInputStream());
			
			bConnected = true;
			
		} catch (BindException e) {
			System.out.println("找不到指定的服务器");
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void disConnect() {
		try {
			if (s != null) {
				s.close();
			}
			
			if (dos != null) {
				dos.close();
			}
			if (dis != null) {
				dis.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String args[]) {
		TCPClient tc = new TCPClient();
		tc.launchFrame();
	}
	
	private class Connect implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (e.getActionCommand() == "连接") {
				
				connectToServer();
				try {
					t.start();
				} catch (IllegalThreadStateException ex) {
					
				}
				
				connect.setText("断开连接");
				
			} else if (e.getActionCommand() == "断开连接") {
				disConnect();
				connect.setText("连接");
			}
			
		}
	}
	
	private class SendMsg implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			if (connect.getActionCommand() == "连接") {
				JOptionPane.showMessageDialog(TCPClient.this,
						"没有找到指定的服务器", "错误提示", 1);
			} else {
				String str = tfTxt.getText();
				tfTxt.setText("");
				
				try {
					dos.writeUTF(str);
					dos.flush();
				} catch (SocketException ex) {
					System.out.println("没有找到指定的服务器");
					JOptionPane.showMessageDialog(TCPClient.this,
							"没有找到指定的服务器", "错误提示", 1);
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			
		}
	}
	
	private class RecToServer implements Runnable {
		public void run() {
			try {
				while (bConnected) {
					String str = dis.readUTF();
					// System.out.println(str);
					
					taContent.append(str + "\n");
				}
			} catch (SocketException e) {
				System.out.println("服务器已关闭");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值