java聊天程序(包含服务端和客户端)

Server:

public class ChatServer {
 boolean stat = false;
 ServerSocket ss = null;
 
 List<Client> clients = new ArrayList<Client>();//用于存客户端
 
 public static void main(String[] args) {
  new ChatServer().start();
 }
 
 public void start(){
  try {
   ss = new ServerSocket(8888);
   stat = true;
  } catch(BindException e){  //Sever端已经运行,当重复运行时抛异常
   System.out.println("端口正在使用中...");
   System.out.println("请关掉相关程序并重新运行服务器!"); //还会抛别的异常,所以直接关闭窗口
   System.exit(0);
  } catch(IOException e) {
   e.printStackTrace();
  }
  
  try{
   while(stat){
    Socket s = ss.accept();
System.out.println("a client connected!" );  //测试语句写在最左边,以后没用可以删除或注掉
    Client c = new Client(s);    //每建立一个客户端,就new一个客户端对象,启动一个线程
    new Thread(c).start();
    clients.add(c);  //勿忘写,将每个客户端加入到容器里
   }
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    ss.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 class Client implements Runnable {
  private Socket s;
  private DataInputStream dis;
  private DataOutputStream dos;
  private boolean cont = false;
  
  public Client(Socket s){
   this.s = s;  
   try {
    dis = new DataInputStream(s.getInputStream());//初始化
    dos = new DataOutputStream(s.getOutputStream());
    cont = true;
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
  
  public void send(String str){  //用于发送给客户端
   try {
    dos.writeUTF(str);
   } catch (IOException e) {
    clients.remove(this);  //移除那个退出的对象
    System.out.println("一个客户退出了");
    //e.printStackTrace();
   }
  }
  
  public void run() {
   try{
    while(cont){
     String str = dis.readUTF(); //阻塞式方法
System.out.println(str);
     for(int i=0; i<clients.size(); i++){
      Client c = clients.get(i);  //取客户端
      c.send(str);  
     }
     /*     另外两种方法,但不适用,它会锁定服务端
     for(Iterator<Client> it = clients.iterator(); it.hasNext();){
      Client c = it.next();
      c.send(str);
     }
     
     Iterator<Client> it = clients.iterator();
     while(it.hasNext()){
      Client c = it.next();
      c.send(str);
     }
     */
    }
   } catch (EOFException e){   //readUTF()阻塞式方法,所以关闭客户端会抛异常
    System.out.println("Client closed!");
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    try {
     if(dis != null) dis.close();
     if(dos != null) dos.close();
     if(s != null) {
      s.close();
      s = null;//更严格的方法,等于空就没人去用了,垃圾收集器就回收走
     }
    } catch (IOException e) {
     e.printStackTrace();
    } 
   }
  }
 }
}
Client:

public class ChatClient extends Frame {
 Socket s = null;
 DataOutputStream dos = null;
 DataInputStream dis = null;
 private boolean cont = false;
 
 TextField tfTxt = new TextField();
 TextArea taContent = new TextArea();
 
 Thread tRecv = new Thread(new RecvThread());
 
 public static void main(String[] args) {
  new ChatClient().launchFrame();
 }
 
 public void launchFrame() {
  setLocation(400, 300);
  this.setSize(300, 300);
  add(tfTxt,BorderLayout.SOUTH);
  add(taContent,BorderLayout.NORTH);
  pack(); //包在一起,去掉中间空着的
  this.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent e){
    disconnect();
    System.exit(0);
   }
  });
  tfTxt.addActionListener(new TfListent());
  setVisible(true);
  connect();
  tRecv.start();   //启动线程
 }
 
 public void connect(){
  try {
   s = new Socket("127.0.0.1",8888);//注意不要定义成Socket s,这就成了局部变量而不是成员变量了
System.out.println("connected!");
   dos = new DataOutputStream(s.getOutputStream());
   dis = new DataInputStream(s.getInputStream());
   cont = true;
  } catch (UnknownHostException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  
 }
 
 public void disconnect(){
  try {
   dos.close(); 
   dis.close();
   s.close();
  } catch (IOException e) {
   e.printStackTrace();
  } 
  
  /*//无法解决readUTF阻塞式方法
  try {
   cont = false;  //关闭线程 
   tRecv.join();  //合并线程,彻底让他停止
  } catch (InterruptedException  e) {
   e.printStackTrace();
  } finally {
   try {
    dos.close(); //线程停止之后才能关流,不然抛SocketException异常
    dis.close();
    s.close();
   } catch (IOException e) {
    e.printStackTrace();
   } 
  }
  */
 }
 
 private class TfListent implements ActionListener {

  public void actionPerformed(ActionEvent e) {
   String str = tfTxt.getText().trim();
   tfTxt.setText("");
   
   try {
    dos.writeUTF(str);
    dos.flush();
 
   } catch (IOException e1) {
    e1.printStackTrace();
   }
   
  }
  
 }

 private class RecvThread implements Runnable{
  
  public void run() {
   try {
    while(cont){
     String str = dis.readUTF();
     taContent.setText(taContent.getText() + str + '\n');
    }
   } catch (SocketException e){
    System.out.println("退出了,bye!");
   } catch (IOException e) {   
    e.printStackTrace();
   }
  }
  
 }
}




public class ChatClient extends JFrame implements ActionListener{ String ip = "127.0.0.1";//连接到服务端的ip地址 int port = 8888;//连接到服务端的端口号 String userName = "匆匆过客";//用户名 int type = 0;//0表示未连接,1表示已连接 Image icon;//程序图标 JComboBox combobox;//选择发送消息的接受者 JTextArea messageShow;//客户端的信息显示 JScrollPane messageScrollPane;//信息显示的滚动条 JLabel express,sendToLabel,messageLabel ; JTextField clientMessage;//客户端消息的发送 JCheckBox checkbox;//悄悄话 JComboBox actionlist;//表情选择 JButton clientMessageButton;//发送消息 JTextField showStatus;//显示用户连接状态 Socket socket; ObjectOutputStream output;//网络套接字输出流 ObjectInputStream input;//网络套接字输入流 ClientReceive recvThread; //建立菜单栏 JMenuBar jMenuBar = new JMenuBar(); //建立菜单组 JMenu operateMenu = new JMenu ("操作(O)"); //建立菜单项 JMenuItem loginItem = new JMenuItem ("用户登录(I)"); JMenuItem logoffItem = new JMenuItem ("用户注销(L)"); JMenuItem exitItem=new JMenuItem ("退出(X)"); JMenu conMenu=new JMenu ("设置(C)"); JMenuItem userItem=new JMenuItem ("用户设置(U)"); JMenuItem connectItem=new JMenuItem ("连接设置(C)"); JMenu helpMenu=new JMenu ("帮助(H)"); JMenuItem helpItem=new JMenuItem ("帮助(H)"); //建立工具栏 JToolBar toolBar = new JToolBar(); //建立工具栏中的按钮组件 JButton loginButton;//用户登录 JButton logoffButton;//用户注销 JButton userButton;//用户信息的设置 JButton connectButton;//连接设置 JButton exitButton;//退出按钮 //框架的大小 Dimension faceSize = new Dimension(400, 600); JPanel downPanel ; GridBagLayout girdBag; GridBagConstraints girdBagCon; public ChatClient(){ init();//初始化程序 //添加框架的关闭事件处理 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); //设置框架的大小 this.setSize(faceSize); //设置运行时窗口的位置 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); this.setLocation( (int) (screenSize.width - faceSize.getWidth()) / 2, (int) (screenSize.height - faceSize.getHeight()) / 2); this.setResizable(false); this.setTitle("聊天客户端"); //设置标题 //程序图标 icon = getImage("icon.gif"); this.setIconImage(icon); //设置程序图标 show(); //为操作菜单栏设置热键'V' operateMenu.setMnemonic('O'); //为用户登录设置快捷键为ctrl+i loginItem.setMnemonic ('I'); loginItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_I,InputEvent.CTRL_MASK)); //为用户注销快捷键为ctrl+l logoffItem.setMnemonic ('L'); logoffItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_L,InputEvent.CTRL_MASK)); //为退出快捷键为ctrl+x exitItem.setMnemonic ('X'); exitItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_X,InputEvent.CTRL_MASK)); //为设置菜单栏设置热键'C' conMenu.setMnemonic('C'); //为用户设置设置快捷键为ctrl+u userItem.setMnemonic ('U'); userItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_U,InputEvent.CTRL_MASK)); //为连接设置设置快捷键为ctrl+c connectItem.setMnemonic ('C'); connectItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_C,InputEvent.CTRL_MASK)); //为帮助菜单栏设置热键'H' helpMenu.setMnemonic('H'); //为帮助设置快捷键为ctrl+p helpItem.setMnemonic ('H'); helpItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_H,InputEvent.CTRL_MASK)); } /** * 程序初始化函数 */ public void init(){ Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); //添加菜单栏 operateMenu.add (loginItem); operateMenu.add (logoffItem); operateMenu.add (exitItem); jMenuBar.add (operateMenu); conMenu.add (userItem); conMenu.add (connectItem); jMenuBar.add (conMenu); helpMenu.add (helpItem); jMenuBar.add (helpMenu); setJMenuBar (jMenuBar); //初始化按钮 loginButton = new JButton("登录"); logoffButton = new JButton("注销"); userButton = new JButton("用户设置" ); connectButton = new JButton("连接设置" ); exitButton = new JButton("退出" ); //当鼠标放上显示信息 loginButton.setToolTipText("连接到指定的服务器"); logoffButton.setToolTipText("与服务器断开连接"); userButton.setToolTipText("设置用户信息"); connectButton.setToolTipText("设置所要连接到的服务器信息"); //将按钮添加到工具栏 toolBar.add(userButton); toolBar.add(connectButton); toolBar.addSeparator();//添加分隔栏 toolBar.add(loginButton); toolBar.add(logoffButton); toolBar.addSeparator();//添加分隔栏 toolBar.add(exitButton); contentPane.add(toolBar,BorderLayout.NORTH); checkbox = new JCheckBox("悄悄话"); checkbox.setSelected(false); actionlist = new JComboBox(); actionlist.addItem("微笑地"); actionlist.addItem("高兴地"); actionlist.addItem("轻轻地"); actionlist.addItem("生气地"); actionlist.addItem("小心地"); actionlist.addItem("静静地"); actionlist.setSelectedIndex(0); //初始时 loginButton.setEnabled(true); logoffButton.setEnabled(false); //为菜单栏添加事件监听 loginItem.addActionListener(this); logoffItem.addActionListener(this); exitItem.addActionListener(this); userItem.addActionListener(this); connectItem.addActionListener(this); helpItem.addActionListener(this); //添加按钮的事件侦听 loginButton.addActionListener(this); logoffButton.addActionListener(this); userButton.addActionListener(this); connectButton.addActionListener(this); exitButton.addActionListener(this); combobox = new JComboBox(); combobox.insertItemAt("所有人",0); combobox.setSelectedIndex(0); messageShow = new JTextArea(); messageShow.setEditable(false); //添加滚动条 messageScrollPane = new JScrollPane(messageShow, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); messageScrollPane.setPreferredSize(new Dimension(400,400)); messageScrollPane.revalidate(); clientMessage = new JTextField(23); clientMessage.setEnabled(false); clientMessageButton = new JButton(); clientMessageButton.setText("发送"); //添加系统消息的事件侦听 clientMessage.addActionListener(this); clientMessageButton.addActionListener(this); sendToLabel = new JLabel("发送至:"); express = new JLabel(" 表情: "); messageLabel = new JLabel("发送消息:"); downPanel = new JPanel(); girdBag = new GridBagLayout(); downPanel.setLayout(girdBag); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 0; girdBagCon.gridy = 0; girdBagCon.gridwidth = 5; girdBagCon.gridheight = 2; girdBagCon.ipadx = 5; girdBagCon.ipady = 5; JLabel none = new JLabel(" "); girdBag.setConstraints(none,girdBagCon); downPanel.add(none); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 0; girdBagCon.gridy = 2; girdBagCon.insets = new Insets(1,0,0,0); //girdBagCon.ipadx = 5; //girdBagCon.ipady = 5; girdBag.setConstraints(sendToLabel,girdBagCon); downPanel.add(sendToLabel); girdBagCon = new GridBagConstraints(); girdBagCon.gridx =1; girdBagCon.gridy = 2; girdBagCon.anchor = GridBagConstraints.LINE_START; girdBag.setConstraints(combobox,girdBagCon); downPanel.add(combobox); girdBagCon = new GridBagConstraints(); girdBagCon.gridx =2; girdBagCon.gridy = 2; girdBagCon.anchor = GridBagConstraints.LINE_END; girdBag.setConstraints(express,girdBagCon); downPanel.add(express); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 3; girdBagCon.gridy = 2; girdBagCon.anchor = GridBagConstraints.LINE_START; //girdBagCon.insets = new Insets(1,0,0,0); //girdBagCon.ipadx = 5; //girdBagCon.ipady = 5; girdBag.setConstraints(actionlist,girdBagCon); downPanel.add(actionlist); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 4; girdBagCon.gridy = 2; girdBagCon.insets = new Insets(1,0,0,0); //girdBagCon.ipadx = 5; //girdBagCon.ipady = 5; girdBag.setConstraints(checkbox,girdBagCon); downPanel.add(checkbox); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 0; girdBagCon.gridy = 3; girdBag.setConstraints(messageLabel,girdBagCon); downPanel.add(messageLabel); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 1; girdBagCon.gridy = 3; girdBagCon.gridwidth = 3; girdBagCon.gridheight = 1; girdBag.setConstraints(clientMessage,girdBagCon); downPanel.add(clientMessage); girdBagCon = new GridBagConstraints(); girdBagCon.gridx = 4; girdBagCon.gridy = 3; girdBag.setConstraints(clientMessageButton,girdBagCon); downPanel.add(clientMessageButton);
当然,我很愿意为您实现一个使用Spring Boot框架的聊天程序服务端客户端。 首先,您需要安装Spring Boot CLI,并在命令行中创建一个Spring Boot项目。然后,您需要添加Web和Socket.IO等相关依赖项,这些依赖项可以帮助您实现聊天功能。 服务端代码: ``` @ServerEndpoint("/chat") public class ChatServer { private static Set<Session> clients = new HashSet<>(); @OnOpen public void onOpen(Session session) { clients.add(session); broadcast("User joined the chat"); } @OnClose public void onClose(Session session) { clients.remove(session); broadcast("User left the chat"); } @OnMessage public void onMessage(String message, Session session) { broadcast(message); } private void broadcast(String message) { for (Session client : clients) { try { client.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } } ``` 客户端代码: ``` <!DOCTYPE html> <html> <head> <title>Chat</title> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script> </head> <body> <div id="message-container"></div> <input type="text" id="message-input" /> <button id="send-button">Send</button> <script type="text/javascript"> var socket = io('http://localhost:8080/chat'); socket.on('connect', function() { console.log('Connected'); }); socket.on('disconnect', function() { console.log('Disconnected'); }); socket.on('message', function(message) { var container = document.getElementById('message-container'); var messageElement = document.createElement('div'); messageElement.innerText = message; container.appendChild(messageElement); }); var input = document.getElementById('message-input'); var button = document.getElementById('send-button'); button.addEventListener('click', function() { socket.emit('message', input.value); input.value = ''; }); </
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值