java简单的聊天室_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java简单的聊天室

java简单的聊天室

 2013/9/4 18:14:43  wangfeiaini  程序员俱乐部  我要评论(0)
  • 摘要:今天在看java网络高级编程,里面的一些例子相当的不错,在这分享一个applet聊天室,不足之处请指正。1.服务端代码:importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.IOException;importjava.io.ObjectInputStream.GetField;importjava.net.ServerSocket;importjava.net.Socket;importjava
  • 标签:Java

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

1. 服务端代码:

class="java" name="code">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();
		}
	}
	
}

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

发表评论
用户名: 匿名