欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java简单的聊天室

程序员文章站 2022-07-03 13:10:29
...

今天在看java网络高级编程,里面的一些例子相当的不错,在这分享一个applet聊天室,不足之处请指正。

1. 服务端代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream.GetField;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

public class ChatServer {
	/**m_threads是一个Vector变量,维护所有Server放的ServerThread对象
	 * 通过该变量能想所有加入聊天室的用户广播信息,撤销退出的聊天者
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Vector m_threads = new Vector();
		System.out.println("listening^");
		try {
			//设置ServerSocket监听端口号为5555(可以自己设定),该端口号必须与客户端的端口号一致
			serverSocket = new ServerSocket(5555);
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		int nid = 0;
		while(true){
			try {
				//监听新的联结者
				Socket s = serverSocket.accept();
				System.out.println("accepted");
				//创建信息聊天线程
				ServerThread st = new ServerThread(s, m_threads);
				//设置用户id
				st.setID(nid++);
				m_threads.addElement(st);
				new Thread(st).start();
				for(int i=0;i<m_threads.size();i++){
					ServerThread ss = (ServerThread) m_threads.elementAt(i);
					ss.write("<#>welcome"+ss.getID()+"to enter chatroom");
				}
				System.out.println("listen again");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	

	/**
	 * 监听线程,监听是否有新的信息传来
	 * @author Administrator
	 *
	 */
	static class ServerThread implements Runnable{
		
		Vector m_threads;
		Socket m_socket = null;
		DataInputStream m_in = null;
		DataOutputStream m_out = null;
		int m_id =0;//线程id
		
		//构造方法创建线程
		 public ServerThread(Socket s,Vector threads) {
			 this.m_socket = s;
			 this.m_threads = threads;
			 try {
				 //构造输入输出流对象
				m_in = new DataInputStream(m_socket.getInputStream());
				 m_out = new DataOutputStream(m_socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		 }
		
		@Override
		public void run() {
			System.out.println("thread running");
			try {
				while(true){
					//线程*在m_in.readUTF(),直到有信息传来
					String s = m_in.readUTF();
					if(s==null) break;
					//如果传来的是leave则通知其他人该用户退出聊天室
					if(s.trim().equals("leave")){
						for (int i = 0; i < m_threads.size(); i++) {
							ServerThread serverThread = (ServerThread) m_threads.elementAt(i);
							serverThread.write("***<"+getID()+">***leave");
						}
					}else{//向所有联结者广播信息
						for (int i = 0; i < m_threads.size(); i++) {
							ServerThread serverThread = (ServerThread) m_threads.elementAt(i);
							serverThread.write("***<"+getID()+">"+s);
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				m_threads.remove(this);//移除退出聊天室的用户线程
				m_socket.close();//关闭socket
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/**
		 * 打印消息
		 * @param msg
		 */
		public void write(String msg){
			try {
				synchronized (m_out) {
					m_out.writeUTF(msg);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public int getID(){
			return m_id;
		}
		
		public void setID(int nid){
			this.m_id = nid;
		}
		
	}
	
}

 2.客户端代码:

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Event;
import java.awt.TextArea;
import java.awt.TextField;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;

public class ChatApplet1 extends Applet implements Runnable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -1670682436342902989L;

	TextArea m_textarea;//接收消息显示窗口
	TextField m_textfield;//消息发送窗口
	DataInputStream m_in;//输入流
	DataOutputStream m_out;//输出流
	
	/**
	 * 初始化聊天室窗口
	 */
	public void init(){
		setLayout(null);
		setSize(426, 226);
		m_textarea = new TextArea(10,10);
		m_textfield = new TextField();
		m_in = null;
		m_out = null;
		try {
			//获取服务器地址
			URL url = getCodeBase();
			//获取服务器ip地址
			InetAddress address = InetAddress.getByName(url.getHost());
			Socket m_socket;
			//打印服务器ip地址 通信协议
			System.out.println("server address:"+address+" "+url.getHost()+" "+url.getProtocol());
			//创建与服务器的链接,端口与服务端口一致
			m_socket = new Socket(address,5555);
			//创建输入输出流
			m_in = new DataInputStream(m_socket.getInputStream());
			m_out = new DataOutputStream(m_socket.getOutputStream());
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		setLayout(new BorderLayout());
		add("Center",m_textarea);
		add("South",m_textfield);
		m_textarea.setEditable(false);
		new Thread(this).start();//启动线程监听
	}
	
	/**
	 * 按下enter键时发送消息
	 */
	@Override
	public boolean handleEvent(Event evt) {
		String b = m_textfield.getText();
		if((evt.target==m_textfield)&&evt.id==Event.ACTION_EVENT){
			m_textfield.setText("");
			try {
				m_out.writeUTF(b);//向服务端发送消息,编码格式UTF-8
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return super.handleEvent(evt);
	}
	
	/**
	 * 监听对应的服务线程,并将聊天信息展示在窗口中
	 */
	@Override
	public void run() {
		while(true){
			try {
				String s = m_in.readUTF();//读取聊天信息
				if(s!=null){
					m_textarea.append(s+"\n");
				}
			} catch (IOException e) {
				e.printStackTrace();
				m_textarea.setText(e.getMessage());
				m_textfield.setVisible(false);
			}
		}
	}

	@Override
	public void stop() {
		super.stop();
		try {
			m_out.writeUTF("leave");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

 核心注释已写上,本人文笔不好,总结的话就不扯啦。