java实现局域网内多人群聊

本文介绍了一个简单的聊天室程序设计,包括服务端与客户端的实现。服务端使用ServerSocket监听指定端口,接受客户端连接请求,并为每个客户端创建独立的任务线程进行消息处理。客户端则通过Socket连接服务端,实现消息的发送与接收。

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

package com.hcj.qqTest;

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

public class Serveic {
	public static void main(String[] args) {
		int port = 8888;
		try {
			//开启服务端socket
			ServerSocket server = new ServerSocket(port);
			while(true){		
				//接收客户端套接字
				Socket client = server.accept();
				Task task = new Task(client);
				task.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


package com.hcj.qqTest;

import java.awt.Frame;
import java.awt.Toolkit;

public class SetFrameCenter {
	//居中
	public static void setCenter(Frame f){
		//获取屏幕大小
		int sWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
		int sHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
		f.setLocation((sWidth - f.getWidth()) / 2, (sHeight - f.getHeight()) / 2);
	}
	//设置大小并居中
	public static void setCenter(Frame f, int width, int height){
		//设置窗口大小
		f.setSize(width, height);
		//获取屏幕大小
		int sWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
		int sHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
		f.setLocation((sWidth - f.getWidth()) / 2, (sHeight - f.getHeight()) / 2);
	}
}


package com.hcj.qqTest;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Task extends Thread {
	private Socket client;
	
	private static Map<String, Socket> map = new HashMap<String, Socket>(); 
	
	public Task(Socket client){
		this.client = client;
		save(client);
	}

	private synchronized void save(Socket client) {
		//储存用户信息
		String hostName = client.getInetAddress().getHostName();
		//将该socket用户添加进map里
		System.out.println("hostName");
		map.put(hostName, client);
	}
	
	@Override
	public void run() {
		try {
			InputStream is = this.client.getInputStream();
			DataInputStream dis = new DataInputStream(is);
			//用户是否退出的标志
			boolean flag = true;
			while(flag){
				String info = dis.readUTF();
				//对所有客户端输出信息
				if(info.equals("exit")){
					String hostName = this.client.getInetAddress().getHostName();
					OutputStream os = this.client.getOutputStream();
					DataOutputStream dos = new DataOutputStream(os);
					dos.writeUTF(hostName + "退出了");
					//删除该用户的socket
					this.map.remove(hostName);
					flag = false;
				}else{
					Collection<Socket> values = map.values();
					System.out.println(values.size());
					for(Socket socket : values){
						OutputStream os = socket.getOutputStream();
						DataOutputStream dos = new DataOutputStream(os);
						dos.writeUTF(info);
					}
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


package com.hcj.qqTest;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientFrame extends JFrame implements ActionListener, KeyListener{
	private JTextArea taMain;
	
	private JPanel panTop,panBottom;
	
	private JButton btnSend;
	
	private JTextField txtMsg;
	
	private JScrollPane sp;
	
	private JLabel lblTitle;
	
	//文本内容
	private StringBuffer content;
	
	//Socket
	private Socket client;
	
	//创建输出流
	private DataInputStream dis;
	
	//创建输入流
	private DataOutputStream dos;
	
	//服务器端地址
	private String serverIp = "192.168.113.214";
	
	//端口号
	private int port = 8888;
	
	public JPanel getPanTop() {
		if(this.panTop == null){
			this.panTop = new JPanel();
			this.panTop.add(this.getLblTitle());
			this.panTop.setBackground(Color.cyan);
		}
		return panTop;
	}

	public JScrollPane getSp() {
		if(this.sp == null){
			this.sp = new JScrollPane(this.getTaMain());
		}
		return sp;
	}

	public JLabel getLblTitle() {
		if(this.lblTitle == null){
			this.lblTitle = new JLabel("单对单聊天室");
		}
		return lblTitle;
	}

	public StringBuffer getContent() {
		if(this.content == null){
			this.content = new StringBuffer();
		}
		return content;
	}

	public static void main(String[] args) {
		new ClientFrame();
	}

	public JTextField getTxtMsg() {
		if(this.txtMsg == null){
			this.txtMsg = new JTextField();
			this.txtMsg.setPreferredSize(new Dimension (320, 28));
			this.txtMsg.addKeyListener(this);
		}
		return txtMsg;
	}

	public JTextArea getTaMain() {
		if(this.taMain == null){
			this.taMain = new JTextArea();
			//设置多行文本框不可编辑
			this.taMain.setEditable(false);
			this.taMain.setBackground(Color.DARK_GRAY);
			this.taMain.setForeground(Color.WHITE);
		}
		return taMain;
	}

	public JPanel getPanBottom() {
		if(this.panBottom == null){
			this.panBottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
			this.panBottom.add(this.getTxtMsg());
			this.panBottom.add(this.getBtnSend());
		}
		return panBottom;
	}

	public JButton getBtnSend() {
		if(this.btnSend == null){
			this.btnSend = new JButton("发送");
			this.btnSend.addActionListener(this);
		}
		return btnSend;
	}
	
	public ClientFrame(){
		init();
		//创建服务器
		createClient();
		//启动读线程
		ClientRead read = new ClientRead(this);
		read.start();
	}

	private void init() {
		this.setTitle("客户端");
		//设置大小并居中
		SetFrameCenter.setCenter(this, 400, 386);
		//添加组件
		appendComponent();
		//默认窗口关闭事件
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		//设置窗口不可变大
		this.setResizable(false);
		//显示窗口
		this.setVisible(true);
	}

	private void appendComponent() {
		this.add(this.getPanTop(), BorderLayout.NORTH);
		this.add(this.getSp(), BorderLayout.CENTER);
		this.add(this.getPanBottom(), BorderLayout.SOUTH);
	}
	
	//创建服务器端ServerSocket
	public void createClient(){
		//创建serverSocket
		try {
			this.client = new Socket(serverIp, port); 
			//创建输入输出流
			this.dis = new DataInputStream(client.getInputStream());
			this.dos = new DataOutputStream(client.getOutputStream());
			//创建读取的线程
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//关流
	public void close(){
		try {
			this.dis.close();
			this.dos.close();
			this.client.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		//通过点击发送实现客户端的写
		if(e.getSource() == this.getBtnSend()){
			//获取文本框内的信息
			String info = this.getTxtMsg().getText();
			//添加后将文本框内容清空
			this.getTxtMsg().setText("");
			//将内容添加到多行文本域里
//			this.getTaMain().append(info + "\n");
			try {
				this.dos.writeUTF(info);
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			if(info.equals("bye")){
				System.out.println("自己已经下线,退出程序");
				//关流
				this.close();
				System.exit(0);
			}
			
		}
	}
	//创建一个读取客户端内容的线程类,并在文本域上显示内容
	class ClientRead extends Thread{
		//获取Server对象
		private ClientFrame sf;
		
		public ClientRead(ClientFrame sf){
			this.sf = sf;
		}
		
		@Override
		public void run() {
			this.sf.getTaMain().append("已连接到客服,请输入内容(注:客服不一定理你,请淡定)" + "\n");
			String info;
			while(true){
				try {
					//获取输出流内容
					info = this.sf.dis.readUTF();
					//将给定文本追加到文档结尾。
					this.sf.getTaMain().append(info + "\n");
					//判断是否是的是bye,如果是bye则退出沟通程序
					if(info.equals("bye")){
						System.out.println("对方已经下线,退出程序");
						//关流
						this.sf.close();
						try {
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.exit(0);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	@Override
	public void keyTyped(KeyEvent e) {
		// 键入某个键时调用此方法
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		//鼠标点击事件
		//返回与此事件中的键关联的字符。
		char keyChar = e.getKeyChar();
		if(keyChar == '\n'){
			//获取回车事件
			this.getBtnSend().doClick();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// 鼠标释放事件
	}
}


这个为和老师学习时写的程序,属于转载。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值