今天在看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(); } } }
?核心注释已写上,本人文笔不好,总结的话就不扯啦。