当前位置: 首页 > news >正文

java socket之多人聊天室Demo

一、功能介绍

该功能实现了一个类似QQ的最简单多人聊天室,如下图所示。

二、目录结构

三、服务端

1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程:

package multiThreadChatSocketServer;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
     private TextArea ta;
     private TextField tf;
     
       private ServerSocket ss;
     private Socket s;
     private DataInputStream dis;
     private DataOutputStream dos;
     
     public TextField getTextField() {
        return tf;
     }
     
     public TextArea getTextArea() {
         return ta;
     }
     
     public DataInputStream getDataInputStream() {
        return dis;
     }
     
     public DataOutputStream getDataOutputStream() {
        return dos;
     }
     
     public static void main(String[] args) {
         SocketServer socketServer = new SocketServer();
         socketServer.createUI();
         socketServer.connect();
         socketServer.createThread();
        }
     
     
     public void close() {
         try {
               dis.close();
               dos.close();
               s.close();
               ss.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
    }

    /**
      * 创建界面
      */
     private void createUI(){
         Frame f=new Frame("socketServer");
         ta = new TextArea();
         tf = new TextField();
         Button send = new Button("send");
         
         Panel p = new Panel();
         p.setLayout(new BorderLayout());
         p.add(tf, "Center");
         p.add(send, "East");
         
         f.add(ta, "Center");
         f.add(p, "South");
         
         MyServerListener listener = new MyServerListener(this);
         //不管点击发送按钮还是输入框回车,都会触发listener事件
         send.addActionListener(listener);
         tf.addActionListener(listener);
         //当关闭窗口的时候,退出系统
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                   System.exit(0);
             }
        });
        f.setSize(400,400);
        f.setVisible(true);
     }
     
     /**
      * 创建连接
      */
     public void connect(){
         try {
            ss=new ServerSocket(8888);
            s=ss.accept();
            dis=new DataInputStream(s.getInputStream());
            dos=new DataOutputStream(s.getOutputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
     /**
      * 启动监听客户端发来的消息的线程
      */
     public void createThread() {
         MyServerReader reader = new MyServerReader(this);
         reader.start();
     }
}

2)MyServerReader类,该类实时监听客户端输入的信息,如果对方输入“bye”,则退出监听并关闭窗口

 

package multiThreadChatSocketServer;

import java.awt.TextArea;
import java.io.DataInputStream;
import java.io.IOException;

/**
 * 监听客户端发过来的消息,关显示在服务端的界面上
 * @author Administrator
 *
 */
class MyServerReader extends Thread {
     private SocketServer server;
     public MyServerReader(SocketServer server) {
         this.server = server;
     }
     public void run() {
         String info;
         DataInputStream dis = server.getDataInputStream();
         TextArea ta = server.getTextArea();
         try {
             while (true) {
                 info = dis.readUTF();
                 ta.append("对方说: " + info + "\n");
                 if (info.equals("bye")) {
                     server.close();
                     System.exit(0);
                 }
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

3)MyServerListener类,是点发送按钮的时候执行的类

package multiThreadChatSocketServer;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

/**
 * 当点击发服务端的送按钮的时候,将信息显示在服务端的界面上,并将信息发送给客户端
 * @author Administrator
 *
 */
class MyServerListener implements ActionListener {
     private SocketServer server;
 
     public MyServerListener(SocketServer server) {
         this.server = server;
     }

     public void actionPerformed(ActionEvent e) {
        TextField tf = server.getTextField();
        String info = tf.getText();
        server.getTextArea().append("自己说: " + info + "\n");
         try {
            // writeUTF(value:String) :将 UTF-8 字符串写入字节流。先写入以字节表示的 UTF-8 字符串长度(作为 16 位整数),然后写入表示字符串字符的字节。 
            // 因为先把字符长度写入二进制,16位能保存的字节长度为65535,超出这个长度会报RangeError。
            // writeUTFBytes(value:String):不添加字节长度直接写入字符串的字节数据。因此在读取的时候需要指定字节长度
            server.getDataOutputStream().writeUTF(info);
         } catch (IOException e1) {
             e1.printStackTrace();
        }
         if (info.equals("bye")) {
             server.close();
             System.exit(0);
         }
        tf.setText("");
        tf.requestFocus();
     }
 }

四、客户端

1)SocketClient类

 

package multiThreadChatSocketClient;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketClient {
     private TextArea ta;
     private TextField tf;
     
     private Socket s;
     private DataInputStream dis;
     private DataOutputStream dos;
     
     public TextField getTextField() {
        return tf;
     }
     
     public TextArea getTextArea() {
         return ta;
     }
     
     public DataInputStream getDataInputStream() {
        return dis;
     }
     
     public DataOutputStream getDataOutputStream() {
        return dos;
     }
     
     public static void main(String[] args) {
         SocketClient socketClient = new SocketClient();
         socketClient.createUI();
         socketClient.connect();
         socketClient.createThread();
        }
     
     
     public void close() {
         try {
               dis.close();
               dos.close();
               s.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
    }

    /**
      * 创建界面
      */
     private void createUI(){
         Frame f=new Frame("socketClient");
         ta = new TextArea();
         tf = new TextField();
         Button send = new Button("send");
         
         Panel p = new Panel();
         p.setLayout(new BorderLayout());
         p.add(tf, "Center");
         p.add(send, "East");
         
         f.add(ta, "Center");
         f.add(p, "South");
         
         MyClientListener listener = new MyClientListener(this);
         //不管点击发送按钮还是输入框回车,都会触发listener事件
         send.addActionListener(listener);
         tf.addActionListener(listener);
         //当关闭窗口的时候,退出系统
         f.addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                   System.exit(0);
             }
        });
        f.setSize(400,400);
        f.setVisible(true);
     }
     
     /**
      * 创建连接
      */
     public void connect(){
         try {
            s = new Socket("127.0.0.1", 8888);
            dis=new DataInputStream(s.getInputStream());
            dos=new DataOutputStream(s.getOutputStream());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
     }
     /**
      * 启动监听服务端发来的消息的线程
      */
     public void createThread() {
         MyClientReader reader = new MyClientReader(this);
         reader.start();
     }
}

2)MyClientReader类

package multiThreadChatSocketClient;

import java.awt.TextArea;
import java.io.DataInputStream;
import java.io.IOException;

/**
 * 监听服务端发过来的消息,关显示在客户端的界面上
 * @author Administrator
 *
 */
class MyClientReader extends Thread {
     private SocketClient client;
     public MyClientReader(SocketClient client) {
         this.client = client;
     }
     public void run() {
         String info;
         DataInputStream dis = client.getDataInputStream();
         TextArea ta = client.getTextArea();
         try {
             while (true) {
                 info = dis.readUTF();
                 ta.append("对方说: " + info + "\n");
                 if (info.equals("bye")) {
                     client.close();
                     System.exit(0);
                 }
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
 }

3)MyClientListener类

package multiThreadChatSocketClient;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

/**
 * 当点击客户端的发送按钮的时候,将信息显示在客户端的界面上,并将信息发送给服务端
 * @author Administrator
 *
 */
class MyClientListener implements ActionListener {
     private SocketClient client;
 
     public MyClientListener(SocketClient client) {
         this.client = client;
     }

     public void actionPerformed(ActionEvent e) {
        TextField tf = client.getTextField();
        String info = tf.getText();
        client.getTextArea().append("自己说: " + info + "\n");
         try {
            client.getDataOutputStream().writeUTF(info);
         } catch (IOException e1) {
             e1.printStackTrace();
        }
         if (info.equals("bye")) {
             client.close();
             System.exit(0);
         }
        tf.setText("");
        tf.requestFocus();
     }
 }

 

相关文章:

  • NCRE考试感想 四级嵌入式(下)
  • ps调整图层
  • 使用zabbix系统批量监控Url返回码
  • 1 weekend110的hdfs源码跟踪之打开输入流 + hdfs源码跟踪之打开输入流总结
  • 支持手机版微信分享显示帖子标题+缩略图+简介】的分享奖励积分插件
  • springMvc源码学习之:spirngMvc的参数注入的问题
  • Rocket - util - LanePositionedQueue
  • URL中带加号的处理
  • XML操作
  • 制作支持UEFI PC的Server2008 R2系统安装U盘
  • c++ 中 毫秒级时间获取
  • golang使用oracle碰到go/lib/time/zoneinfo.zip: no such file or directory
  • Introduction to Machine Learning
  • Windows Server 2012 R2上安装.Net4.6.1出错
  • 解决操作缓冲池重复添加的问题
  • JS 中的深拷贝与浅拷贝
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • [数据结构]链表的实现在PHP中
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Flannel解读
  • iOS编译提示和导航提示
  • Javascript基础之Array数组API
  • js ES6 求数组的交集,并集,还有差集
  • js学习笔记
  • JWT究竟是什么呢?
  • laravel5.5 视图共享数据
  • mongo索引构建
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • SAP云平台里Global Account和Sub Account的关系
  • session共享问题解决方案
  • 订阅Forge Viewer所有的事件
  • 那些被忽略的 JavaScript 数组方法细节
  • 使用 Docker 部署 Spring Boot项目
  • 思否第一天
  • 通过几道题目学习二叉搜索树
  • 以太坊客户端Geth命令参数详解
  • 优化 Vue 项目编译文件大小
  • 昨天1024程序员节,我故意写了个死循环~
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​VRRP 虚拟路由冗余协议(华为)
  • #HarmonyOS:基础语法
  • (1)(1.9) MSP (version 4.2)
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (算法)Game
  • (转)项目管理杂谈-我所期望的新人
  • ./configure,make,make install的作用(转)
  • .gitignore文件_Git:.gitignore
  • .libPaths()设置包加载目录
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET 药厂业务系统 CPU爆高分析