聊天室-原生java实现

拒绝吹牛逼

拒绝吹牛逼

拒绝吹牛逼

直接上图(先看效果)这里只演示了4个客户端

这是包结构,就两个类,一个readem

下面先来客户端

下面来服务器端

 

本来不打算发源码的,怎么可能呐?

下附源码

//客户端
package com.fendou.chat;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

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;

/**
 * 聊天室客户端
 * @author fendou
 */

public class ChatClient extends JFrame{
	
	Socket socket;
	PrintWriter out;
	BufferedReader in;
	JPanel p;
	JScrollPane sp;
	JTextArea txtContent;
	JLabel lblName,lblSend;
	JTextField txtName,txtSend;
	JButton btnSend;
	
	public ChatClient() {
		
		super("客户聊天");
		txtContent = new JTextArea();
		// 设置文本域只读
		txtContent.setEditable(false);
		sp = new JScrollPane(txtContent);
		lblName = new JLabel("姓名:");
		txtName = new JTextField(5);
		lblSend = new JLabel("请输入:");
		txtSend = new JTextField(20);
		btnSend = new JButton("发送");
		p = new JPanel();
		p.add(lblName);
		p.add(txtName);
		p.add(lblSend);
		p.add(txtSend);
		p.add(btnSend);
		this.add(p,BorderLayout.SOUTH);
		this.add(sp);
		this.setSize(500, 400);// 宽500,高400
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		try {
			// 创建一个套接字
			socket = new Socket("127.0.0.1",1218);
			// 创建一个往套接字中写数据的管道,即输出流,给服务器发送信息
			out = new PrintWriter(socket.getOutputStream());
			// 创建一个从套接字读数据的管道,即输入流,读服务器的返回信息
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (UnknownHostException e) {
			e.printStackTrace();
			System.out.println("没有找到主机或主机未打开。");
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// 注册监听
		btnSend.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// 获取用户输入的文本
				String strName = txtName.getText();
				String strMsg = txtSend.getText();
				if(!strMsg.equals("")) {
					// 通过输出流将数据发送给服务器
					out.println(strName+"说:"+strMsg);
					out.flush();
					// 清空文本框
					txtSend.setText("");
				}
			}
		});
		// 启动线程
		new GetMsgFromServer().start();
	}
	
	// 接收服务器的返回信息
	class GetMsgFromServer extends Thread {
		public void run() {
			while(this.isAlive()) {
				
				try {
					String strMsg = in.readLine();
					
					if(strMsg != null) {
						// 在文本域中显示聊天信息
						txtContent.append(strMsg+"\n");
					}
					Thread.sleep(50);
					
				} catch (Exception e) {
					e.printStackTrace();
				}	
			
			}
			
		}
		
	}
	
	public static void main(String[] args) {
		
		ChatClient f = new ChatClient();
		f.setVisible(true);
		
	}

}

/**
 * 上述代码在构造方法中先创建客户端图形界面,然后创建一个Socket连接服务器,
 * 并获取Socket的输入流和输出流,用于对Socket中的数据进行读/写。
 * 当用户点击“发送”按钮时,将用户在文本框中输入的数据通过输出流写到Socket中,并发送给服务器。
 * 启动GetMsgFromServer线程,通过输入流循环接收服务器发送的返回信息。
 * 
 * 
 */


//服务器端
package com.fendou.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 * 聊天室服务器端
 * @author fendou
 */

public class ChatServer {
	
	ServerSocket serverSocket;
	ArrayList<BufferedReader> ins = new ArrayList<BufferedReader>();
	ArrayList<PrintWriter> outs = new ArrayList<PrintWriter>();
	LinkedList<String> msgList = new LinkedList<String>();
	
	public ChatServer() {
		
		try {
			serverSocket = new ServerSocket(1218);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// 创建 AcceptSocketThread 线程,并启动
		new AcceptSocketThread().start();
		// 创建 SendMsgToClient 线程,并启动
		new SendMsgToClient().start();
		System.out.println("Server Start...");
		
	}
	
	// 接收客户端套接字线程
	class AcceptSocketThread extends Thread{
		public void run() {
			while(this.isAlive()) {
				
				try {
					// 接收套接字
					Socket socket = serverSocket.accept();
					if(socket != null) {
						BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
						ins.add(in);
						outs.add(new PrintWriter(socket.getOutputStream()));
						// 开启一个线程接收客户端的聊天信息
						new GetMsgFromClient(in).start();
						
					}
					
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
	
	// 接收客户的聊天信息的线程
	class GetMsgFromClient extends Thread {
		BufferedReader in;
		public GetMsgFromClient(BufferedReader in) {
			this.in = in;
		}
		
		public void run() {
			while(this.isAlive()) {
				
				try {
					String strMsg = in.readLine();
					
					if(strMsg != null) {
						msgList.add(strMsg);
					}
					
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
		
	}
	
	// 给所有客户发送聊天信息的线程
	class SendMsgToClient extends Thread{
		
		public void run() {
			
			while(this.isAlive()) {
				try {
					if(!msgList.isEmpty()) {
						String s = msgList.removeLast();
						for(int i = 0;i < outs.size(); i++) {
							outs.get(i).println(s);
							outs.get(i).flush();
						}
					}
				}catch (Exception e) {
					e.printStackTrace();
				}
				
			}
			
		}
		
	}
	
	
	public static void main(String[] args) {
		
		new ChatServer();
		
	}
	
	
}


/**
 * 上述代码中,服务器端应用程序有多个线程:
 * 
 * AcceptSocketThread 线程用于循环接收客户端发来的Socket连接,
 * 并将与该Socket通信的输入流和输出流保存到ArrayList集合中;
 * 
 * GetMsgFromClient 线程用于接收客户端发来的聊天信息,
 * 并将信息保存到LinkedList集合中;
 * 
 * SendMsgToClient 线程用于将LinkedList集合中的聊天信息发给所有客户端。
 * 
 * 
 */

 

创作不易,多多支持!如果您觉得对您有帮助,点个赞或者打赏一下再走嘛!

 

END

 

发布了149 篇原创文章 · 获赞 41 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览