多线程聊天室


  • 利用 Java 的网络套接字和 Swing ,设计一个简单的网络多线程聊天室。

一、服务器套接字

  • 首先是服务器端的套接字,其具体代码如下:

    package chating;// !/usr/bin/env jdk1.8
    // encoding:utf-8
    //@software:IntelliJ IDEA
    //@pack:chating
    //@user:彭友聪
    //@date:2019/07/27
    //@time:上午 9:47
    //@project:IDEA_JAVA
    //@file:ChatRoomServer.java
    //Author:御承扬
    //email:2923616405@qq.comimport java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.HashSet;public class ChatRoomServer {private ServerSocket serverSocket; // 服务器套接字private HashSet<Socket> allSockets; // 客户端套接字集合// 聊天室构造方法public ChatRoomServer(){try {serverSocket = new ServerSocket( 4569 );} catch (IOException e) {e.printStackTrace();}allSockets = new HashSet<>(  ); //  实例化客户端套接字集合}// 启动聊天室的方法private void startService() throws IOException {int i=0;while(true) {i++;Socket s = serverSocket.accept(); // 获得一个客户端连接System.out.printf( "用户%d已经进入聊天室\n",i );allSockets.add(s);new ServerThread(s).start();}}// 服务器线程内部类private class ServerThread extends Thread {Socket socket; // 客户端套接字ServerThread(Socket socket) {this.socket = socket;}public void run() {BufferedReader br = null;try {// 将客户端套接字输入流转为字节流读取br = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );while (true ) {String str = br.readLine(); // 读取到一行之后,则赋值给字符串if(str.contains("%EXIT%")) { // 如果文本内容包含"%EXIT%"allSockets.remove( socket ); // 集合删除此客户端连接// 服务器向所有客户端接口发出退出通知sendMessageToAllClient(str.split( ":" )[1]+"用户已退出聊天室");socket.close();return;}sendMessageToAllClient(str); // 向所有客户端发送此客户端发送来的文本消息}} catch (IOException e) {e.printStackTrace();}}/* ** 发送消息给客户端的方法** @param message*/final void sendMessageToAllClient(String message) throws IOException {for (Socket s : allSockets) { // 循环集合中所有的客户端连接PrintWriter pw = new PrintWriter( s.getOutputStream() ); // 创建输出流pw.println( message ); // 输入写入文本pw.flush();}}public static void main(String[] args) {try {new ChatRoomServer().startService();} catch (IOException e){e.printStackTrace();}}
    }
    

二、客户端套接字

  • 有了服务器套接字,就要有与之相配套的客户端套接字,代码如下:

    package chating;// !/usr/bin/env jdk1.8
    // encoding:utf-8
    //@software:IntelliJ IDEA
    //@pack:chating
    //@user:彭友聪
    //@date:2019/07/27
    //@time:上午 10:14
    //@project:IDEA_JAVA
    //@file:ChatRoomClient.java
    //Author:御承扬
    //email:2923616405@qq.com/**   聊天室客户端*/import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;public class ChatRoomClient {private Socket socket; // 客户端套接字private BufferedReader bufferedReader; // 字节流读取套接字输入流private PrintWriter pWriter; // 字节流写入套接字输出流/** 聊天室客户端构造方法* @param host*          服务器 IP 地址* @param port*          服务器与客户端互联的端口*/public ChatRoomClient(String host, int port) throws UnknownHostException, IOException {socket = new Socket( host, port ); // 连接服务器bufferedReader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); // 字节流读取套接字输入流pWriter = new PrintWriter( socket.getOutputStream() ); // 字节流写入套接字输出流}/** 聊天室客户端发送消息的方法* @param str 客户端发送的消息*/public final void sendMessage(String str) {pWriter.println( str );pWriter.flush();}/** 聊天客户端获取消息的方法* @return 读取某个客户端发送的消息*/final String receiveMessage() {try {return bufferedReader.readLine();} catch (IOException e) {e.printStackTrace();}return null;}/** 关闭套接字*/public final void close() {try {socket.close();} catch (IOException e) {e.printStackTrace();}}
    }
    

三、用户界面

  • 前面两个部分,是属于后台部分,接下来是属于前台部分的用户界面。
  • 用户界面由两个部分组成,一个登陆和连接界面,一个是聊天界面。

登陆连接界面

  • 登陆连接界面的代码如下:

    package chating;// !/usr/bin/env jdk1.8
    // encoding:utf-8
    //@software:IntelliJ IDEA
    //@pack:chating
    //@user:彭友聪
    //@date:2019/07/27
    //@time:下午 4:28
    //@project:IDEA_JAVA
    //@file:LinkServerFrame.java
    //Author:御承扬
    //email:2923616405@qq.comimport javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;public class LinkServerFrame extends JFrame {private LinkServerFrame() {setLayout( null );setBounds(540,200, 400,250 );setVisible( true );setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );JLabel lbIP = new JLabel( "服务器 IP 地址:" );lbIP.setBounds( 10,10,100,30 );lbIP.setVisible( true );JLabel userName = new JLabel( "用户名:" );userName.setBounds( 40,60,50,30 );userName.setVisible( true );JTextField jfIP = new JTextField(  ); // IP 地址输入框jfIP.setBounds( 110,10,250,30 );jfIP.setVisible( true );JTextField jfUser = new JTextField(  );jfUser.setBounds( 110,60,250,30 );jfUser.setVisible( true );JButton btn = new JButton( "连接服务器" );btn.setBounds( 120,100,100,20 );btn.setVisible( true );btn.addActionListener( new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (!jfIP.getText().equals( "" ) && !jfUser.getText().equals( "" )) {dispose(); // 销毁当前窗体// 创建客户端窗体并传参ClientFrame clientFrame = new ClientFrame( jfIP.getText().trim(), jfUser.getText().trim() );} else {JOptionPane.showMessageDialog( null,"文本框里的内容不能为空!","警告",JOptionPane.WARNING_MESSAGE );}}} );Container center = getContentPane();center.add(lbIP);center.add( jfIP );center.add( userName );center.add( jfUser );center.add( btn );center.setBackground( Color.WHITE );}public static void main(String[] args) {new LinkServerFrame();}
    }
    
  • 运行效果如下图:

聊天界面

  • 聊天界面的代码如下:

    package chating;// !/usr/bin/env jdk1.8
    // encoding:utf-8
    //@software:IntelliJ IDEA
    //@pack:chating
    //@user:彭友聪
    //@date:2019/07/27
    //@time:下午 3:31
    //@project:IDEA_JAVA
    //@file:ClientFrame.java
    //Author:御承扬
    //email:2923616405@qq.comimport javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.IOException;
    import java.net.UnknownHostException;
    import java.text.SimpleDateFormat;
    import java.util.Date;public class ClientFrame extends JFrame {private JTextField tfMessage; // 信息发送文本框private JTextArea textArea; // 信息接收文本域private ChatRoomClient client; // 客户端连接对象// 构造方法public ClientFrame(String ip, String userName) {super("多线程聊天室");setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );setLayout( null );setBounds( 100,50,800,680 );Container c = getContentPane();// 用户名称this.addWindowListener( new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent atg0) {int op = JOptionPane.showConfirmDialog( ClientFrame.this,"确定要退出聊天室吗?", "确定", JOptionPane.YES_NO_OPTION); // 弹出提示框if (op == JOptionPane.YES_OPTION) {client.sendMessage( "%EXIT%:"+userName ); // 发送信息try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}client.close();System.exit( 0 );}}} );// 发送按钮JButton btnSend = new JButton( "发送" );btnSend.setBounds( 680,550,100,30 );btnSend.setVisible( true );btnSend.addActionListener( new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {Date date = new Date();SimpleDateFormat df = new SimpleDateFormat( "yyyy年MM月dd日 HH:mm:ss" ); // 设定日期格式client.sendMessage( userName+" "+df.format( date )+": \n"+tfMessage.getText() ); // 向服务器发送消息tfMessage.setText(""); // 输入框为空}} );// 实例化客户端对象try {client = new ChatRoomClient( ip,4569 ); // 创建客户端对象} catch(UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}ReadMessageThread messageThread = new ReadMessageThread(); // 创建读取客户端消息的线程类对象messageThread.start();// 控件初始化JLabel text = new JLabel( "消息对话框:" );text.setBounds( 10,0,200,30 );text.setVisible( true );// 消息对话框textArea = new JTextArea(  );textArea.setBounds( 10,30,750,420 );textArea.setVisible( true );textArea.setBackground( Color.LIGHT_GRAY);textArea.setFont(new Font("标楷体", Font.BOLD, 16)); //设置当前字体。// 显示用户名JLabel lblUserName = new JLabel( userName );lblUserName.setBounds( 10,550,50,30 );lblUserName.setVisible( true );tfMessage = new JTextField(  );tfMessage.setBounds( 50,550,600,30 );tfMessage.setVisible( true );// 下方面板c.add(text);c.add(textArea);c.add(lblUserName);c.add(tfMessage);c.add(btnSend);c.setBackground( Color.WHITE );setVisible( true );}private class ReadMessageThread extends Thread{private ReadMessageThread() {}public void run() {while (true) {String str = client.receiveMessage(); // 客户端收到服务器发来的文本内容textArea.append( str+"\n" ); // 向文本框添加内容}}}public static void main(String[] args) {new ClientFrame( "192.168.0.105", "吴雅男" );}
    }
    
  • 先运行服务器套接字,在运行连接界面两次,效果如下:

Java 网络编程实例—多线程聊天室相关推荐

  1. Java网络编程——多人聊天室

    多用户即时通信系统 需求分析: 1.用户登录 2.拉取在线用户列表 3.无异常退出 4.私聊 5.群聊 6.发送文件 7.服务器推送新闻 多用户登录 老韩的课程讲的真的很清楚: 关于Java多线程的文 ...

  2. Java网络编程,一对一聊天

    Java网络编程,一对一聊天 **这个小任务是来自于B站,他的视频名字就是"Java实现实时聊天互动程序"** 要求:就是有2个类,其中一个客户端和一个服务端.要实现从客户端发消息 ...

  3. java网络编程实现一个聊天程序

    网络编程 l网络模型 OSI参考模型 TCP/IP参考模型 l网络通讯要素 IP地址 端口号 传输协议 网络参考模型 网络通讯要素 lIP地址:InetAddress 网络中设备的标识 不易记忆,可用 ...

  4. Linux下Socket网络编程之点对点聊天室

    1. 系统设计的目的与意义 掌握信号与信号处理的概念,了解点对点聊天室的设计需求,掌握相关的理论知识,切实掌握程序设计的分析方法,勇于实践,多参考开源项目和代码.实现点对点聊天室程序设计,Linux网 ...

  5. Java网络编程实例---------------------------------基本HTTP客户端及服务端多线程

    HTTP 1.0客户端 package com.bq;import java.io.BufferedReader; import java.io.InputStreamReader; import j ...

  6. java网络编程实例_关于java网络编程的实例代码

    服务器端的写法 package com.chinasofti.corejava.ch22; import java.io.BufferedReader; import java.io.IOExcept ...

  7. java网络编程-聊天室

    目录 V01 # 聊天室客户端(V1) # 聊天室服务端(V1) V02 # 聊天室客户端(V2) # 聊天室服务端(V2) V03 V04 # 聊天室客户端(V4) # 聊天室服务端(V4) V05 ...

  8. Java网络编程,使用Java实现UDP和TCP网络通信协议,以及基于UDP的在线聊天室。

    文章目录 前言 一.网络编程概念 1.网络 2. 网络编程的目的 3.想要达到这个效果需要什么 4.网络分层 二.网络编程Java类 1.IP地址:InetAddress 2.端口 3.TCP连接 3 ...

  9. java网络编程,通过TCP,Socket实现多对一的局域网聊天室

    java网络编程,通过TCP,Socket实现多对一的局域网聊天室 可以实现多个客户端连接服务器,服务器接收到信息就会把信息广播到所有的客户端 这是服务器端的代码 View Code import j ...

  10. c语言tcp多线程聊天室,66 网络编程(五)——TCP多线程实现多人聊天室

    思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...

最新文章

  1. 我仅使用到的dd if
  2. php还原json,PHP语言中使用JSON和将json还原成数组
  3. python excel 模块 性能_【xlwings1】Python-Excel 模块哪家强
  4. 对mysql的各种sql语句如何对表加锁的实验
  5. 物理学家杨振宁到底有多厉害?
  6. 相机标定(2)opencv2实现
  7. GROUP BY你都不会!ROLLUP,CUBE,GROUPPING详解
  8. 教程-Delphi资源文件(全面分析于使用)
  9. java中文输出乱码_java汉字乱码解决办法
  10. 机器学习基石 作业二
  11. CMSIS到底是个什么东西
  12. macsv服务器状态,MACS5应用
  13. oracle共享池使用率,oracle调优之--共享池使用问题(摘自文平书)
  14. 07-11-Exchange Server 2019-配置-Outlook 2019-IMAP4
  15. 清空RMON统计的数据
  16. 如何向oracle中导入数据,Oracle导入导出数据库的语法_Oracle_Oracle语法_Oracle数据库_课课家...
  17. HTTP编程(Java爬虫-简单爬取网页数据)
  18. C++ primer 第五版 练习题记录
  19. fir.im Weekly - 当技术成为一种“武器”
  20. 【电机学】【公式速查】感应电动机、异步电动机

热门文章

  1. (附源码)spring boot记账微信小程序 毕业设计 180815
  2. java-php-python-ssm校园流浪猫图鉴管理系统的设计与实现计算机毕业设计
  3. 有限元法 matlab,MATLAB有限元分析与应用.pdf
  4. 那智机器人作业原点位置设定
  5. 64位计算机比32快多少,电脑系统应该选择64位还是32位 到底哪个速度更快?
  6. 怎么转换kux格式?教你把优酷的kux格式转换成avi
  7. OSEK NM 功能测试
  8. tkmybatis详细教程(一篇就明白)
  9. nestjs连接mysql数据库的方法与使用
  10. 群晖系统设定定时NTP同步时间