package myk.chat; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector; public class ChatServer { /** * 聊天服务者server的主方法,该方法监听聊天着chatApplet的请求,并为新连接的聊天者创建一个新线程 */ public static void main(String[] args) { ServerSocket socket = null; /**m_theads是一个静态变量,维护server方的所有ServerThread对象,通过该变量向所有加入聊天室的人发送信息 * 撤销退出的聊天着。*/ Vector m_theads = new Vector(); System.out.println("listen...."); try { /**设置服务器端的端口号,必须和客户端的一致*/ socket = new ServerSocket(5555); } catch (IOException e) { System.out.println("new ServerSocket() failed!!"); } try { int nid = 0; while (true) { /*** * 监听是否有新聊天着连接服务器,线程运行到这块,会封锁,直到新的连接产生 */ Socket s = socket.accept(); System.out.println("accpted!"); /**创建一个新的ServerThread*/ ServerThread st = new ServerThread(s,m_theads); /**设置id号*/ st.setId(nid++); /**将线程加入到m_theads Vector中*/ m_theads.add(st); /**启动服务线程*/ new Thread(st).start(); /**通知所有线程,有新成员加入*/ for(int i=0;i <#>welcome "+st.getId()+" to enter chatroom!"); } System.out.println(" listen again!"); } } catch (IOException e) { System.out.println(" server is down!"); } } }
package myk.chat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Vector; /**监听线程,监听对应的ChatApplet是否有信息传来*/ public class ServerThread implements Runnable{ Vector m_threads; Socket m_socket = null; DataInputStream m_in = null; DataOutputStream m_out = null; int m_nid; //初始化线程 public ServerThread(Socket s,Vector threads){ m_socket = s; m_threads = threads; try { //构造输入输出流对象 m_in = new DataInputStream(m_socket.getInputStream()); m_out = new DataOutputStream(m_socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } public void run() {//线程的执行体 System.out.println("Thread is running!!!"); try { while(true){ //监听对应的ChatApplet是否有信息传来 //线程封锁在这块,直到有信息传来 String s = m_in.readUTF(); if(s==null){ break; } //如果传来信息leave,则向所有用户通知该用户离开 if(s.trim().equals("leave")){ for(int i=0;i ******"+getId()+" leave"+" *****"); } } else{ //否则向所有用户发送信息 for( int i=0;i ******"+getId()+" :"+s); } } } } catch (IOException e) { e.printStackTrace(); } } //将msg送回对应的Applet public void write(String msg) { synchronized(m_out){ try { m_out.writeUTF(msg); } catch (IOException e) { e.printStackTrace(); } } } public int getId() { return m_nid; } public void setId( int mid){ this.m_nid = mid; } }
package myk.chat; 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; public class ChatApplet1 extends Applet implements Runnable{ TextArea m_textArea;//接受消息显示窗口 TextField m_textField;//发送消息输入窗口 DataInputStream m_in;//消息输入流 DataOutputStream m_out;//消息输出流 /** * ChatApplet的初始化方法 */ public void init(){ setLayout(null); setSize(426,426); m_textArea = new TextArea(10,10); m_textField = new TextField(); m_in = null; m_out = null; try { //初始化Applet,并连接到服务着 URL url = getCodeBase(); InetAddress inetAddress = InetAddress.getByName(url.getHost()); Socket m_socket; //显示服务器ip地址,及通信协议 System.out.println("server:"+inetAddress+url.getHost()+url.getProtocol()); m_socket = new Socket(inetAddress,5555); //在套接口上建立输入流 m_in = new DataInputStream(m_socket.getInputStream()); //在套接口上建立输入流 m_out = new DataOutputStream(m_socket.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } setLayout(new BorderLayout()); add("Center",m_textArea); add("South",m_textField); m_textArea.setEditable(false); //启动监听线程 new Thread(this).start(); } /** * 当在聊天窗口输入消息,按回车键,即可发送给chatServer */ public boolean handleEvent(Event event){ String b = m_textField.getText(); if((event.target==m_textField)&& event.id==Event.ACTION_EVENT ){ m_textField.setText(""); try { //向聊天室发送utf格式的字符串 m_out.writeUTF(b); } catch (IOException e) { e.printStackTrace(); } return true; }else{ return super.handleEvent(event); } } public void run() { try { while(true){ String s = m_in.readUTF();//读一个UTF格式的字符串 if(s!=null){ //将消息显示在信息显示窗口中 m_textArea.append(s+"/n"); } } } catch (IOException e) { m_textArea.append("Netword problem or server down. /n "); m_textField.setVisible(false); } } public void stop(){ try { m_out.writeUTF("leave"); } catch (IOException e) { e.printStackTrace(); } } }