ChatRoom 聊天室设计文档

 

ChatRoom 聊天室设计文档

ChatRoom 聊天室程序功能简介:

      服务器接受每个连接客户发来的信息,再广播给每个客户。

Server:

       服务器 ChatRoomServer 启动后自动监听默认端口:DEFAULT_PORT 6666等待客户的连接,当有客户连接上来时,在文本域显示连接信息。

       服务器端点击窗口关闭或点击窗体内的退出按钮可以关闭服务器。

Client:

       客户端ChatRoomClient 启动后显示客户端界面:窗体上方有一个连接按钮和一个文本筐(文本筐在按钮的右面)。在文本筐中输入服务器地址,再按左边的连接按钮或按键盘上的Enter键,连接服务器。如果连接成功将显示连接成功信息,否则将显示连接失败信息。

       连接成功后客户可以在窗体底部消息标签右边的文本筐中输入要发送的消息,然后点击文本筐右边的发送按钮或按键盘上的”Enter“键发送信息。

       客户端受到的信息将显示在窗体中部的文本域中。

 

ChatRoomServer.java——说明:

      //由于在程序中做了较多注释,所以这里只做简单的叙述:

1.程序启动是初始化界面、并开始监听:

           public ChatRoomServer(){

              try{

                     jbInit();

              }catch(Exception e){

                     e.printStackTrace();

              }

              serverListen();//服务器开始监听

       }

    jbInit(){、、、、}初始化界面,注册button1(退出)按钮和窗口关闭事件。

serverListen(){、、、}打开并监听端口:6666

2public void run(){//接受连接并记录线程信息

       、、、、、、

       try{

              while(true){

clientSock=serverSock.accept();

              CommunicateThread ct=new CommunicateThread(clientSock,this,index);//创建线程保持连接

                            clients.add(ct);//记录连接信息到clients数组

                            clientsInfor.add("Thread-"+i);//记录连接名称

                     、、、、、、、、、

       }

CommunicateThread ct=new CommunicateThread(clientSock,this,index);

当有连接上来时,创建线程以保持连接。

3public void exit(){、、、}

       退出并关闭seversock

4.class CommunicateThread extends Thread{、、、、}//保持连接线程

5 class BroadcastThread extends Thread{、、、}//广播线程

6//处理窗口关闭事件的适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{、、、}

 

 

ChatRoomClient.java——说明:

1             初始化窗体

public ChatRoomClient(){

              try{

                     jbInit();

              }catch(Exception e){

                     e.printStackTrace();

              }

       }

       jbInit(){、、、、}初始化窗体,将button1(连接)、button2(发送)注册到ActionListener,textField1(服务器地址) 、textField2(消息)注册到keyListener,将窗体注册到WindowListener

2  StartConnect(){、、、、}//连接服务器

       点击button1或在textField1中按“Enter”键后调用startConnect()连接服务器并启动线程run(),读取服务器广播来的信息,打印到文本区域。

3public void exit(){、、、}//窗口关闭;如果有连接则关闭连接和相关的""

4//文本筐textField1的键击事件适配器

class textField1_KeyAdapter extends java.awt.event.KeyAdapter{}

5//文本筐textField2的键击事件适配器

class textField2_KeyAdapter extends java.awt.event.KeyAdapter{}

6//窗口关闭事件适配器

class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{}

聊天室服务器端源程序:

package chatserver2;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class ChatRoomServer extends Frame implements Runnable{
 Panel panel;
 ScrollPane sPanel;
 TextArea textArea;
 Button button1;
 
 //net
 ServerSocket serverSock;
 public final static int DEFAULT_PORT=6666;//
默认端口号
 Thread chatAcceptThread;//
启动接受连接的线程
 BroadcastThread broadcastThread;//
广播thread; run when server is listening
 java.util.Vector clients;//
记录连接的线程
 java.util.Vector clientsInfor;//
记录连接线程的信息
 public static int index=0;
 
 public ChatRoomServer(){
  try{
   jbInit();
  }catch(Exception e){
   e.printStackTrace();
  }
  serverListen();//
服务器开始监听
 }
 
 private void jbInit(){//
初始化界面
  panel=new Panel();
  sPanel=new ScrollPane();
  textArea=new TextArea("server information:/n");
  button1=new Button("
退出");
  
  sPanel.add(textArea);
  
  button1.addActionListener(new java.awt.event.ActionListener(){//
退出按钮注册
   public void actionPerformed(ActionEvent e){
    button1_actionPerformed(e);
   }
  });
  panel.add(button1);
  
  this.addWindowListener(new ChatFrame_WindowAdapter(this));//
注册到继承了窗口适配器的类
  this.setSize(600,600);
  this.setLayout(new BorderLayout());
  this.add(sPanel,BorderLayout.CENTER);
  this.add(panel,BorderLayout.SOUTH);
  this.show();
  
 }
 
 private void button1_actionPerformed(ActionEvent e){
  exit();
 }
 
 public void processMsg(String str){//
  textArea.append(str);
 }
 
 private void serverListen(){
  try{
   serverSock=new ServerSocket(DEFAULT_PORT);
  }catch(IOException e){
   processMsg(e.toString());
   processMsg("server failed!/n");
  }
  processMsg("server listening on port:"+DEFAULT_PORT);
  clients=new java.util.Vector();
  clientsInfor=new java.util.Vector();
  
  chatAcceptThread=new Thread(this);//
启动接受连接的线程
  chatAcceptThread.start();
  
  broadcastThread=new BroadcastThread(this);//
广播线程
  broadcastThread.start();
  
  //
还有一个回收无用连接thread 的线程
 }
  
 public void run(){//
接受连接并记录线程信息
  int i=0;
  try{
   while(true){
    Socket clientSock=serverSock.accept();
    CommunicateThread ct=new CommunicateThread(clientSock,this,index);//
创建线程保持连接
    clients.add(ct);//record Communicate Thread;
    i++;
    index++;//version2
    clientsInfor.add("Thread-"+i);

 processMsg("Thread-"+i+"join in/n");
    
   }
  }catch(IOException e){
   processMsg(e.toString());
  } 
 }
 
 public void exit(){
  broadcastThread.broadcast("Server exit!");
  try{
   serverSock.close();
  }catch(IOException ioe){}
  finally{
   System.exit(0);
  }
 }
 
 public static void main(String[] args){
  ChatRoomServer chat=new ChatRoomServer();
 }
}

class CommunicateThread extends Thread{//保持连接线程
 protected Socket clientSock;
 protected BufferedReader in=null;
 protected PrintWriter out;
 ChatRoomServer chatFrame;
 boolean isTrue=true;//run()
 java.util.Vector inforStack;
 int index2;//
 
 public CommunicateThread(Socket Sock,ChatRoomServer cFrame,int index){
  clientSock=Sock;
  chatFrame=cFrame;
  index2=index;
  inforStack=new java.util.Vector();
  try{
   in=new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
   out=new PrintWriter(clientSock.getOutputStream());
  }catch(IOException ei){
   try{
    clientSock.close();
   }catch(IOException ei2){ }
   chatFrame.processMsg(ei.toString());
   return;
  }
  this.start();
 }
 
 public void run(){
  String infor;
  try{
   while(isTrue){
    infor=in.readLine();
    if(infor.equals("Client exit!")){
     writeInformation(infor);//
把信息写到信息栈,以倍广播出去
     stopRun();
    }else if(infor!=null){
     writeInformation(infor);
    }//else break;
    try{
     Thread.sleep(100);//version2
    }catch(InterruptedException ex){}
   }
  }catch(IOException e){ ;}
  finally{
   try{
    in.close();
    out.close();
    clientSock.close();
    chatFrame.clients.remove(index2);//
clients中清除本线程序
    ChatRoomServer.index--;//
   }catch(IOException ei){;}
  }
  
 }
 
 public void writeInformation(String infor){//
写信息栈
  inforStack.add(infor);
 }
 
 private void stopRun(){//
终止线程
  isTrue=false;
 }
 
 public void sendInformation(String str){//
发送信息
  try{
   out.println(str);
   out.flush();
  }catch(Exception e){;} 
 }  
}

class BroadcastThread extends Thread{//广播线程
 ChatRoomServer chatFrame2;
 java.util.Vector chatClients;//
连接线程信息

java.util.Vector msgStack;//信息栈
 java.util.Vector clientMsg;//
记录客户发送的信息
 CommunicateThread comThread1;
 CommunicateThread comThread2;
 String string;//information in inforStack
 String clientName;//client thread name
 String broadcastInfor;//broadcast information=clientName+string;
 
 public BroadcastThread(ChatRoomServer cFrame){
  chatFrame2=cFrame;
  chatClients=chatFrame2.clients;
  clientMsg=chatFrame2.clientsInfor;
  //this.start();
 }
 
 public void broadcast(String str){//
广播  
  for(int k=0;k<chatClients.size();k++){//send to everyone
分别调用每个连接线程,发送信息

   comThread2=(CommunicateThread)chatClients.get(k);
   comThread2.sendInformation(str);
  }
 }
 
 public void run(){
  try{
   while(true){
    for(int i=0;i<chatClients.size();i++){
     comThread1=(CommunicateThread)chatClients.get(i);
     msgStack=comThread1.inforStack;//
得到每个连接的信息栈

     clientName=(String)clientMsg.get(i);//
客户名
     //
读取每个连接线程的信息栈并把信息发送出去

     for(int j=0;j<msgStack.size();j++){
      string=(String)msgStack.get(j);
      broadcastInfor=clientName+"->"+string;
      broadcast(broadcastInfor);
     }
     //clear the inforStack
     msgStack.removeAllElements();//
清除以发送的信息
     
    }
    try{
     Thread.sleep(100);//version2
    }catch(InterruptedException ex){}
   }
  }catch(Exception e){}
 }
 
}

//处理窗口关闭事件的适配器
class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{
 ChatRoomServer chatFrame;
 public ChatFrame_WindowAdapter(ChatRoomServer chatFrame){
  this.chatFrame=chatFrame;
 }
 public void windowClosing(WindowEvent e){//exit program
  chatFrame.exit();//reference to the method exit() in ChatRoomServer.
 }
}

 

聊天室客户端源程序:

 

package chatclient_test;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class ChatRoomClient extends Frame implements Runnable{
 Panel panel1,panel2;
 Button button1,button2;
 TextField textField1,textField2;
 Label label1;
 TextArea textArea;
 ScrollPane sPanel;
 //net
 PrintWriter out;
 BufferedReader in=null;
 
Socket sock;
 public final static int DEFAULT_PORT=6666;
 
 //create Thread to Read information from Server
 Thread readThread;
 boolean isTrue=true;//thread can go on runing ??

public ChatRoomClient(){
  try{
   jbInit();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 
 public static void main(String[] args){//main method
  ChatRoomClient c=new ChatRoomClient();
  c.show();
 }
 
 private void jbInit(){//should set size,position and Font of every component
  
  button1=new Button("
连接
");// set Font
  button2=new Button("
发送
");
  textField1=new TextField("input Server address here!");
  textField2=new TextField("input Message here and send to server");
  label1=new Label("
消息
:");
  panel1=new Panel();
  panel2=new Panel();
  sPanel=new ScrollPane();
  textArea=new TextArea();
  
  //panel1 
  //press button1:
连接
to connect the client to server
  button1.addActionListener(new java.awt.event.ActionListener(){
   public void actionPerformed(ActionEvent e){
    button1_actionPerformed(e);
   }
  });
  //textField1:for input the address of server;be registered to KeyListener.
  //press key:Enter to connect the client to server
  textField1.addKeyListener(new textField1_KeyAdapter(this));//java.awt.event.KeyAdapter()
  panel1.add(button1);
  panel1.add(textField1);
  
  //sPanel  ScrollPane
  sPanel.add(textArea);
  
  //panel2
  //press button2:
发送
to send message
  button2.addActionListener(new java.awt.event.ActionListener(){
   public void actionPerformed(ActionEvent e){
    button2_actionPerformed(e);
   }
  });
  //textField2:for input message;be registered to KeyListener.
  //press key:Enter to send message
  textField2.addKeyListener(new textField2_KeyAdapter(this));
  panel2.add(label1);
  panel2.add(textField2);
  panel2.add(button2);
  
  //frame
  this.addWindowListener(new ChatFrame_WindowAdapter(this));//frame is registered to WindowListener
  this.setLayout(new BorderLayout());
  this.setSize(500,400);
  this.add(panel1,BorderLayout.NORTH);
  this.add(sPanel,BorderLayout.CENTER);
  this.add(panel2,BorderLayout.SOUTH);
  //this.show()
    
 }
  
 public void startConnect(){//
开始连接

  try{
   sock=new
Socket(textField1.getText(),DEFAULT_PORT);
   if(sock!=null){//connection successed
    processMsg("Connect successfully!");
   }
   in=new BufferedReader(new InputStreamReader(sock.getInputStream()));
   out=new PrintWriter(sock.getOutputStream());
  }catch(IOException ex){
processMsg(ex.toString());
   processMsg("Connect failed!");
  }
  
  readThread=new Thread(this);
  readThread.start(); 
 }
 
 //public void endConnect(){//close IOstream
 
 public void sendInformation(){
  out.println(textField2.getText());
  out.flush();
  
 }
 
 private void button1_actionPerformed(ActionEvent e){//
连接按钮

  startConnect();
 }
   
 private void button2_actionPerformed(ActionEvent e){//
发送按钮
  sendInformation();
 }
   
 public void stopRun(){//to stop the running thread
  isTrue=false;
 } 
   
 public void processMsg(String msg){//
客户端处理消息
  textArea.append(msg);
  textArea.append("/n");
 }
 
 public void run(){
  String msg;
  isTrue=true;
  while(isTrue){
   try{
    msg=in.readLine();
    if(msg.equals("Server exit!")){//server exit
     processMsg(msg);
     stopRun();//
终止线程
    }else if(msg!=null){
     processMsg(msg);
    }
    Thread.sleep(1000);    
   }catch(IOException e){
    processMsg(e.toString());
   }catch(InterruptedException ei){
    processMsg(ei.toString());
   }
  }
  //endConnect();
  try{//
服务器退出关闭连接和相关的""
   sock.close();
   in.close();
   out.close();
  }catch(IOException ioe){} 
 }
 
 public void exit(){//
窗口关闭;如果有连接则关闭连接和相关的"
"
  try{//send "Client exit!" to Server!
   out.println("Client exit!");
   out.flush();
  }catch(Exception exc){}
  //endConnect();
  try{//close IOstream
   sock.close();
   in.close();
   out.close();
  }catch(IOException ioe){}
  finally{ 
   System.exit(0);
  }
 }
}

//文本筐textField1的键击事件适配器
class textField1_KeyAdapter extends java.awt.event.KeyAdapter{
 ChatRoomClient chatFrame;
 
 public textField1_KeyAdapter(ChatRoomClient chatFrame){
  this.chatFrame=chatFrame;
 }
 
 public void keyPressed(KeyEvent e){//
输入的是enter,开始连接!
  int j=e.getKeyCode();
  if(j==e.VK_ENTER){
   chatFrame.startConnect();
  }
 }
}

//文本筐textField2的键击事件适配器
class textField2_KeyAdapter extends java.awt.event.KeyAdapter{
 ChatRoomClient chatFrame;
 
 public textField2_KeyAdapter(ChatRoomClient chatFrame){
  this.chatFrame=chatFrame;

}
 
 public void keyPressed(KeyEvent e){//
键击Enter键,发送信息!

  int j=e.getKeyCode();
  if(j==e.VK_ENTER){
   chatFrame.sendInformation();
  }
 }
}

//窗口关闭事件适配器
class ChatFrame_WindowAdapter extends java.awt.event.WindowAdapter{
 ChatRoomClient chatFrame;
 public ChatFrame_WindowAdapter(ChatRoomClient chatFrame){
  this.chatFrame=chatFrame;
 }
 public void windowClosing(WindowEvent e){//exit program
  chatFrame.exit();//reference to the method exit() in ChatRoomClient.
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
chatRoom.zip 聊天室聊天室服务端 package chatroom; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import javax.swing.JFrame; import javax.swing.JOptionPane; /** * 聊天室服务器ChatRoomServer类 * * @version 1.01, 09/04/10 */ public class ChatRoomServer { private ServerSocket ss; /* 存放Socket的集合hs */ private HashSet<Socket> hs; public ChatRoomServer() { JFrame jf = new JFrame(); do { /* * 弹出输入对话框,提示输入服务器需要绑定的端口号 */ int port = Integer.parseInt(JOptionPane.showInputDialog(jf, "bind port:")); try { ss = new ServerSocket(port); System.out.println("server start success,now listening port:" + port); } catch (Exception e) { /* 弹出确认框进行确认 */ int op = JOptionPane.showConfirmDialog(jf, // 指定是在jf中弹出确认框 "bind fail,retry?", // 框体内容 "bind fail", // 对话框的标题 JOptionPane.YES_NO_OPTION); // 确认框按钮项 /* 如果选择'否',则退出程序 */ if (op == JOptionPane.NO_OPTION) { System.exit(1); } /* 打印异常栈信息 */ e.printStackTrace(); } } while (ss == null); /* 创建HashSet,用来存放Socket对象 */ hs = new HashSet<Socket>(); while (true) { try { /* 获得Socket,网络阻塞,等待客户端的连接 */ Socket s = ss.accept(); /* 一旦客户端连接上,则加入HashSet,便于维护 */ hs.add(s); /* 启动一个服务线程,为客户端服务 */ new ServerThread(s).start(); } catch (IOException e) { e.printStackTrace(); } } } /** * 成员内部类,服务线程类 */ class ServerThread extends Thread { private Socket s; public ServerThread(Socket s) { this.s = s; } @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(s .getInputStream())); while (true) { /* 从网络中读取客户端发出的消息 */ String str = br.readLine(); /* * 客户退出时的处理逻辑 规则:以"%EXIT_CHATROOM%"开头的消息为客户退出标记 */ if (str.charAt(0) == '%') { String com = str.split("%")[1]; if (com.equals("EXIT_CHATROOM")) { hs.remove(s); printMessage(str.split("%")[2] + ",leave!"); s.close(); break; } } else { /* 正常情况,直接向客户端群发消息 */ printMessage(str); } } } catch (IOException e) { e.printStackTrace(); } } /* * 负责为客户端群发消息 */ private void printMessage(String mes) { System.out.println(mes); try { /* 遍历所有Socket */ for (Socket s : hs) { PrintStream ps = new PrintStream(s.getOutputStream()); /* 产生发消息的时刻 */ Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); /* 向客户端发消息,消息结构为mes [yyyy-MM-dd HH:mm:ss] */ ps.println(mes + " [" + sdf.format(date) + "]"); /* 注意需要及时flush,清空缓冲区 */ ps.flush(); } } catch (IOException e) { e.printStackTrace(); } } } /* * 主方法,启动聊天室服务器端 */ public static void main(String[] args) { new ChatRoomServer(); } } 客户端窗体 package chatroom; import java.awt.BorderLayout; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 客户端窗口ChatRoomClientFrame类 负责客户端的视图表示、事件处理等逻辑 作为一个窗口,所以本类继承自JFrame * 为了实现事件处理,本类实现了ActionListener接口 * * @version 1.01, 09/04/10 */ public class ChatRoomClientFrame extends JFrame implements ActionListener { private static final long serialVersionUID = 3484437496861281646L; private JTextArea jta; // 多行文本域 private JLabel label; // 文本标签 private JTextField jtf; // 单行文本框 private JButton jb; // 按钮 private Socket socket; // socket 套接字 private String name; // 用户名 /* * ChatRoomClientFrame构造方法,负责初始化以及添加事件处理 */ public ChatRoomClientFrame(String name, Socket socket) { super("chatroom"); Font f = new Font("楷体", Font.BOLD, 20); /* 设置字体 */ jta = new JTextArea(10, 10); /* 创建10行10列的空多行文本域 */ jta.setEditable(false); /* 设置多行文本域为不可编辑 */ jta.setFont(f); /* 设置多行文本域字体 */ label = new JLabel(name + ":"); /* 创建带有用户名的文本标签 */ label.setFont(f); /* 设置文本标签字体 */ jtf = new JTextField(25); /* 创建单行文本框 */ jtf.setFont(f); /* 设置单行文本框字体 */ jb = new JButton("send"); /* 创建按钮 */ this.name = name; this.socket = socket; init(); /* 初始化,设置组件关系 */ addEventHandler(); /* 为组件添加事件监听 */ } /* * 初始化组件关系方法,供构造方法调用 */ private void init() { JScrollPane jsp = new JScrollPane(jta); this.add(jsp, BorderLayout.CENTER); JPanel jp = new JPanel(); jp.add(label); jp.add(jtf); jp.add(jb); this.add(jp, BorderLayout.SOUTH); } /* * 负责为各组件添加事件处理机制 */ private void addEventHandler() { jb.addActionListener(this); // 为jb添加事件监听,JButton点击触发事件 jtf.addActionListener(this); // 为jtf添加事件监听,JTextField敲回车触发事件 /* 设置JFrame默认关闭状态:DO_NOTHING_ON_CLOSE */ this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); /* 为JFrame添加窗口事件监听 */ this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent arg0) { /* 弹出确认框进行交互 */ int op = JOptionPane.showConfirmDialog( ChatRoomClientFrame.this, "exit?", "exit", JOptionPane.YES_NO_OPTION); if (op == JOptionPane.YES_OPTION) { try { PrintStream ps = new PrintStream(socket .getOutputStream()); /* 向服务器发送以%EXIT_CHATROOM%name为格式的串,代表退出信号 */ ps.println("%EXIT_CHATROOM%" + name); /* 注意需要及时flush */ ps.flush(); try { Thread.sleep(168); // 进行延时控制,防止提前关闭socket } catch (InterruptedException e) { e.printStackTrace(); } socket.close(); // 关闭客户端socket ps.close(); // 关闭流 } catch (IOException e) { e.printStackTrace(); } System.exit(1); // 退出程序 } } }); } /* * 实现事件处理方法 */ public void actionPerformed(ActionEvent ae) { try { PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(name + ": " + jtf.getText()); ps.flush(); /* 清空jtf中内容 */ jtf.setText(""); } catch (IOException e) { e.printStackTrace(); } } /* * 显示并执行窗口逻辑 */ public void showMe() { this.pack(); // 自动调整此窗口的大小 this.setVisible(true); // 设置窗口可见 /* * 启动线程,负责接收服务器端发来的消息 */ new Thread() { @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(socket .getInputStream())); while (true) { /* 从网络中读取服务器发出的数据 */ String str = br.readLine(); /* 对JTextArea进行追加消息 */ jta.append(str + "\n"); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } } 客户端 package chatroom; import java.io.PrintStream; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JOptionPane; /** * 聊天室客户端 ChatRoomClient * * @version 1.01, 09/04/10 */ public class ChatRoomClient { private String name; // 用户名 private Socket socket; // Socket 套接字 private ChatRoomClientFrame frame; // 组合复用 ChatRoomClientFrame /* * ChatRoomClient构造方法,负责构造客户端表示逻辑 */ public ChatRoomClient() { JFrame jf = new JFrame(); /* * 弹出用户输入对话框,提示用户输入服务器的IP地址 返回相应字符串形式,存于变量serverIP,缺省值127.0.0.1 */ String serverIP = JOptionPane.showInputDialog(jf, "server IP:", "127.0.0.1"); /* * 弹出用户输入对话框,提示用户输入服务器端口号 转化为int形式返回,存于变量serverPort */ int serverPort = Integer.parseInt(JOptionPane.showInputDialog(jf, "port:")); /* * 弹出用户输入对话框,提示用户输入用户名,存于成员属性name */ name = JOptionPane.showInputDialog(jf, "your name:"); try { /* 通过IP和Port,与服务器端建立连接 */ socket = new Socket(serverIP, serverPort); /* 给服务器发消息 */ PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(name + ",login !"); } catch (Exception e) { JOptionPane.showMessageDialog(jf, "fail,check the connection!"); e.printStackTrace(); System.exit(1); } /* * 创建ChatRoomClientFrame,进行客户端主窗口的显示 */ frame = new ChatRoomClientFrame(name, socket); frame.showMe(); } /* * 主方法,启动聊天室客户端 */ public static void main(String[] args) { new ChatRoomClient(); } }
以下是使用JavaWeb实现聊天室的步骤: 1.创建一个JavaWeb项目,命名为ChatRoom。 2.在项目中创建一个名为ChatServlet的Servlet,用于处理聊天室的逻辑。 3.在ChatServlet中,使用WebSocket技术建立长连接,实现服务器和客户端之间的双向通信。 4.在ChatServlet中,处理客户端发送的消息,并将消息广播给所有在线用户。 5.在ChatServlet中,处理用户加入和退出聊天室的逻辑,并将相关信息广播给所有在线用户。 6.在项目中创建一个名为index.jsp的JSP页面,用于展示聊天室界面。 7.在index.jsp中,使用JavaScript代码实现与服务器的WebSocket连接,并处理用户发送消息、加入和退出聊天室的逻辑。 8.在index.jsp中,使用HTML和CSS代码实现聊天室的界面。 下面是一个简单的JavaWeb聊天室的示例代码,仅供参考: ```java @WebServlet("/chat") public class ChatServlet extends WebSocketServlet { private static final long serialVersionUID = 1L; private static final List<Session> sessions = new CopyOnWriteArrayList<>(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/index.jsp").forward(request, response); } @Override public void configure(WebSocketServletFactory factory) { factory.getPolicy().setIdleTimeout(10000); factory.setCreator(new ChatSocketCreator()); } private static class ChatSocketCreator implements WebSocketCreator { @Override public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) { return new ChatSocket(); } } private static class ChatSocket implements WebSocketListener { private Session session; @Override public void onWebSocketBinary(byte[] arg0, int arg1, int arg2) { } @Override public void onWebSocketClose(int arg0, String arg1) { sessions.remove(session); broadcast("User " + session.getId() + " has left the chat room."); } @Override public void onWebSocketConnect(Session session) { this.session = session; sessions.add(session); broadcast("User " + session.getId() + " has joined the chat room."); } @Override public void onWebSocketError(Throwable arg0) { } @Override public void onWebSocketText(String message) { broadcast(session.getId() + ": " + message); } private void broadcast(String message) { for (Session session : sessions) { try { session.getRemote().sendString(message); } catch (IOException e) { e.printStackTrace(); } } } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值