Java网络编程之多客户端之间的通信(简单的即时聊天)

Java网络编程之Tcp实现多人聊天 网络编程 用Tcp实现多人聊天窗口 实现思路 具体思路: ​ 1、写一个server服务器,用于监听10001端口,以及处理接收和向客户端发出数据。 ​ 2、客户端寻找服务器的ip地址与服务器端口。建立连接。 ​ 3、每个客户端与服务器建立连接后,创建一个InputStream流和一个OutputStream流用于传输数据。 同时客户端将自己的用户信息对象通过ObejcetOutputStrea... 阅读详情

前面实现了服务器与多个客户端之间的通信,我们真正的目的是要实现多个客户端之间的通信

使用TCP协议实现的方案:

客户端的数据包通过服务器中转,发送到另一个客户端

 实现步骤:

1、对象序列化:(对象需要在网络上传输)

数据包(发送消息者,接收消息者,消息类型(登录、发送),发送的消息内容)

2.定义消息类型:

 消息类型:登录、发送

有兴趣的,可以自己扩展其他消息类型,如注册、退出等消息类型 

3、服务器:

启动服务器、用动态序列容器Vector保存在服务器中保存的所有线程的任务对象、每个对象创建一个线程来处理

4、客户端:

启动客户端、发送登录信息、接收消息的线程、处理消息发送的线程

 

代码实现:

1、对象序列化:

package com.lemon.communication;

import java.io.Serializable;

/**
 * 消息包
 * @author lemonsun
 */
public class Message implements Serializable {

    private String from; //发送者
    private String to;   //接收者
    private int type; //消息类型
    private String info;//消息包

    public Message() {
    }

    public Message(String from, String to, int type, String info) {
        this.from = from;
        this.to = to;
        this.type = type;
        this.info = info;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

2、定义消息类型

package com.lemon.communication;

/**
 * @author lemonsun
 */
public class MessageType {

    public static final int TYPE_LOGIN = 0x1; //登录消息类型
    public static final int TYPE_SEND = 0x2;  //发送消息的类型
}

3、服务器

package com.lemon.communication;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 服务器:
 * @author lemonsun
 */
public class Server {
    public static void main(String[] args) {
        //保存客户端处理的线程
        Vector<UserThread> vector = new Vector <>();
        //固定大小的线程池,用来处理不同客户端
        ExecutorService es = Executors.newFixedThreadPool(5);
        //创建服务器端的Socket
        try {
            ServerSocket server = new ServerSocket(8888);
            System.out.println("服务器以启动,正在等待连接...");
            while(true){
                //接受客户端的Socket,若没有,阻塞在这
                Socket socket = server.accept();
                //每来一个客户端,创建一个线程处理它
                UserThread user = new UserThread(socket,vector);
                es.execute(user);  //开启线程
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 客户端处理线程:
 */
class UserThread implements Runnable{
    private String name; //客户端的用户名称,唯一
    private Socket socket;
    private Vector<UserThread> vector;   //客户端处理线程的集合
    private ObjectInputStream oIn;    //输入流
    private ObjectOutputStream oOut;  //输出流
    private boolean flag = true;  //标记

    public UserThread(Socket socket, Vector<UserThread> vector) {
        this.socket = socket;
        this.vector = vector;
        vector.add(this);    //把当前线程也加入vector中
    }

    @Override
    public void run() {
        try {
            //1、构造输入输出流
            System.out.println("客户端:" + socket.getInetAddress().getHostAddress() + "已连接!");
            oIn = new ObjectInputStream(socket.getInputStream());
            oOut = new ObjectOutputStream((socket.getOutputStream()));
            //2、循环读取
            while(flag){
                //读取消息对象
                Message message = (Message)oIn.readObject();
                //获取消息类型,登录还是发送消息
                int type = message.getType();
                //3、判断
                switch (type){
                    //如果是发送消息
                    case MessageType.TYPE_SEND:
                        String to = message.getTo();//发送给谁
                        UserThread ut;
                        //遍历vector,找到接收信息的客户端
                        int size = vector.size();
                        for (int i = 0; i < size; i++) {
                            ut = vector.get(i);
                            //如果名字相同,且不是自己,就把信息发给它
                            if(to.equals(ut.name) && ut != this){
                                ut.oOut.writeObject(message); //发送消息对象
                            }
                        }
                        break;
                    //如果是登录
                    case MessageType.TYPE_LOGIN:
                        name = message.getFrom();//获取用户名
                        message.setInfo("欢迎您!");//设置登录成功信息
                        oOut.writeObject(message);
                        break;
                }

            }



        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

4、客户端:

package com.lemon.communication;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 客户端:
 *
 * @author lemonsun
 */
public class Client {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //单线程池
        ExecutorService es = Executors.newSingleThreadExecutor();
        try {
            //创建客户端
            Socket socket = new Socket("localhost", 8888);
            System.out.println("服务器连接成功!");
            //构建输出输入流
            ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream());
            //1、客户端登录处理
            //向服务器发送登录信息(名字和消息类型)
            System.out.println("请输入名称:");
            String name = input.nextLine();
            //登录时,只自己的名字和消息类型为登录
            Message message = new Message(name, null, MessageType.TYPE_LOGIN, null);
            //发送给服务器
            oOut.writeObject(message);
            //服务器返回 欢迎信息
            message = (Message) oIn.readObject();
            //打印服务器返回的信息+当前客户端的名字
            System.out.println(message.getInfo() + message.getFrom());
            //2、启动读取消息的线程
            es.execute(new readInfoThread(oIn));  //读取线程完成

            //3、发送消息
            //使用主线程来发送消息
            boolean flag = true;
            //循环
            while(flag){
                //创建对象
                message = new Message();
                //发给谁
                System.out.println("To:");
                message.setTo(input.nextLine());
                //谁发的,从自己这发
                message.setFrom(name);
                //类型 发送消息
                message.setType(MessageType.TYPE_SEND);
                //发送的内容
                System.out.println("Info:");
                message.setInfo(input.nextLine());
                /*----到此需要发送的消息 对象 封装完毕----*/
                //发送给服务器
                oOut.writeObject(message);
            }
            
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 读取其他客户端发来消息
 */
class readInfoThread implements Runnable {
    private ObjectInputStream oIn; //输入流 用来读操作
    private boolean flag = true; //标记

    public readInfoThread(ObjectInputStream oIn) {
        this.oIn = oIn;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {

        try {
            //循环 不断读取消息
            while (flag) {
                //读取信息
                Message message = (Message) oIn.readObject();
                //输出用户名+内容
                System.out.println("[" + message.getFrom() + "]对我说:" + message.getInfo());
            }
            //没有数据就关闭
           if(oIn != null){
               oIn.close();
           }

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }


    }
}

开启服务器,开启几个客户端,就可以相互通信啦

 

 

 

 

 

 

 

 

 

 

java实现的网站发送短信功能 现在有好多网站都偶有发送短信给用户的功能,基本都依靠与电信或移动的运营商,这个例子就是包括了所有的步骤,教你一步一步学习 立即下载

相关推荐

即时通信系统(Java实现)

即时通信系统(Java实现),完整版,可供大家参考学习

Java通信原理(3)——多客户端连接(1)

Java、TCP/IP、Socket、通信

qq_64037280的博客 2337

java实现的即时通讯

java实现即时通讯:客户端通过socket连接服务器和其他客户端socket线程通信

java多线程实现服务器端与多个不同端口客户端通信

server端: import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; // 服务器类 public class MyServer { ...

weixin_42046520的博客 2093

PPO算法详解:基于CartPole-v1的强化学习实现

PPO算法详解:基于CartPole-v1的强化学习实现

m0_54720701的博客 865

车载机器人终极解决方案:从功能叠加到生态融合的颠覆性变革

本文提出一种融合智能汽车与家居技术的车载机器人架构。其创新点包括:1)基于多模态传感器的拟人化硬件设计,实现声源定位误差<5°、体温检测精度±0.3℃;2)跨模态情感计算引擎,综合面部表情、心率等数据构建三维情绪模型;3)协议自适应中间件,支持小米、华为等多品牌智能家居设备即插即用;4)环境自适应舵机控制,-30℃环境下扭矩保持率达92.5%。测试数据显示,该方案使交互步骤减少60%,用户满意度提升58%,日均使用时长增加2.3倍,为"人-车-家"生态融合提供了可行技术路径。

qq_42671193的博客 1128

介绍几种java中网络通信的方式

1.TCP方式(以下内容转自孙卫琴老师的相关讲义) 在客户/服务器通信模式中,服务器端需要创建监听特定端口的ServerSocket,ServerSocket负责接收客户连接请求。本章首先介绍ServerSocket类的各个构造方法,以及成员方法的用法,接着介绍服务器如何用多线程来处理与多个客户的通信任务。 本章提供线程池的一种实现方式。线程池包括一个工作队列和若干工作线程。服务器程序向工作队

alwaysloving的专栏 3262

2025东三省D题深圳杯数学建模实战解析:基于多模型融合的法医STR混合样本智能识别系统

本文深入解析了2025年东三省数学建模竞赛D题,即深圳杯赛题,聚焦于法医STR混合样本的智能识别挑战。文章系统阐述了构建一个基于多模型融合的智能识别系统的完整流程,涵盖贡献者人数判定、DNA贡献比例估计、个体基因型推断以及STR谱图去噪四大核心步骤。通过融合高斯混合模型、随机森林、非负矩阵分解、小波变换与深度学习等多种技术,并强调特征工程的重要性,为破解法医DNA混合样本分析这一行业难题提供了清晰的数学建模与AI实战思路。

weixin_29050271的博客 392

Java实现TCP一服务端对多客户端Socket通信网络编程

TCP协议特点: 面向连接,只能由客户端主动发送数据给服务端,服务端接收到数据后可以给客户端响应 通过三次握手建立连接,四次挥手断开连接 基于IO流进行数据传输,传输大小没有限制 速度慢,传输可靠 使用场景: 文件上传下载 邮件发送接收 远程登陆 TCP通信也叫Socket网络编程 Socket 一个该类对象代表一个客户端程序 构造器 public Socket(String host,...

qq_41112238的博客 2994

服务器冗余电源维修图纸,冗余热备份电源的电路图设计

在设计某高可靠性计算机系统时,要求其配套电源采取冗余设计。一般来说,可以采取的方案有容量冗余、冗余冷备份方式、并联均流的N+1备份方式、冗余热备份方式。容量冗余是指电源的最大负载能力大于实际负载,也就是“大马拉小车”,其缺点是不利于提高电源的效率,而且对提高电源的可靠性意义不大。冗余冷备份方式是指电源由两个或多个功能相同的单元模块组成,电源启动后由其中一个单元模块向设备供电,当工作单元发生故障时,...

weixin_39671509的博客 1995

MOSFET导通电阻Rdson全解析:物理组成、公式推导与工程选型要点

在功率电子设计中,MOSFET作为核心开关器件,其导通电阻Rdson直接决定导通损耗与系统效率。从半导体物理角度看,Rdson并非单一固定值,而是由源极电阻、沟道电阻、累积层电阻、JFET区电阻、漂移区电阻及衬底电阻等多个分量串联而成,并随栅极驱动电压、结温以及击穿电压等级发生显著变化。理解Rdson的物理来源与数学表达,有助于工程师在低压大电流与高压小电流等不同场景中合理选型、优化驱动电压并准确估算热损耗。文章从沟道电阻公式出发,深入剖析耐压与导通电阻的物理矛盾、温度系数的影响规律,并给出数据手册参数的正

weixin_29163857的博客 197

4、Java网络编程—服务器与多客户端通信

4、服务器与多客户端通信 目前为止我们编写的程序中,服务器只能同时处理一个客户端连接,要想服务器同时支持多个客户端的连接,就必须加入多线程的处理机制,将每一个连接的客户端都创建一个新的线程对象。 服务器端 import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorServi

weixin_53330986的博客 1462

深度学习-155-RAG技术之嵌入模型Embedding怎么选

Embedding技术在大型语言模型中发挥着至关重要的作用。它将文本转化为向量,使模型能够理解和处理复杂的语言信息。通过选择合适的Embedding方法和优化文本匹配策略,我们可以在搜索引擎、问答系统、推荐系统等领域实现高效且精准的文本匹配。

qq_20466211的博客 405

执行时长2分钟的SQL,AI帮我优化到10毫秒。AI优化神器,你值得拥有

执行时长2分钟的SQL,AI帮我优化到10毫秒??sql优化神器上线了

小草的博客 6429

Windows版,vcenter 6.0 STS 证书更新--Vcenter 6.0 windows 版,没有-set_signing_cert 替换参数

Windows版,vcenter 6.0 STS 证书手动更新

技术是手段,服务才是目的。开源与协作是创新的活水,而核心技术的自主可控是立足之本。身处黄金时代,唯持续学习,方能不惧变化。从使用者到创造者,中国技术的未来,正待你们接过火炬,走得更远、更稳、更好。 678

【100%通过率】华为od机试C卷【出差 / 员工派遣】Java&Go 实现

某公司部门需要派遣员工去国外做项目。现在,代号为 x 的国家和代号为 y 的国家分别需要 cntx 名和 cnty 名员工部门每个员工有一个员工号 (1,2,3,......),工号连续,从 1开始。部长派遣员工的规则:

MISAYAONE的博客 2640

人脸识别模型大升级,口罩检测识别率高达99%

疫情期间,口罩成了人们出门必戴的装备。这给人们带来安全感的同时,也带来了挑战,比如进出小区、学校、办公楼等场所时,门禁的人脸识别系统很难识别“蒙面大侠”,致使人们不得不摘下口罩。为了让通...

百度智能云 1129

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

一图看懂 linecache 模块:随机读写文本行, 资料整理+笔记(大全)

全文介绍系统内置 os 模块、函数、类及类的方法和属性。它通过代码抓取并经AI智能翻译和人工校对。是一部不可多得的权威字典类工具书。它是系列集的一部分。后续陆续发布、敬请关注。【原创:AhcaoZhu大侠】

常年招收【在读】大学生、研究生、IT一技之长者,远程兼职,待遇丰厚!请私信我! 1034

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

输入法漏洞总结篇

输入法漏洞是一个很经典的漏洞,相信大家以前零零散散都玩过本人总结了下出现了的几个输入法漏洞再配合以前一些经典入侵的事例希望对大家有所帮助,或许在入侵过程中有用呢说明:本人只是做个总结,以上引用了不少大侠的文章<<全拼输入法漏洞入侵>>一,获得管理员账号: 我们先对一个网段进行扫描,扫描端口设为3389,运行客户端连接管理器,将...

weixin_34357887的博客 2675

java多客户端之间的通信

共四个类文件 1: import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.ExecutorServi...

qq_37422923的博客 446

Java实现简易即时通讯系统

本文介绍了一个基于Java的简易即时通讯系统(类似QQ),采用客户端-服务器架构实现核心功能。系统主要包括服务器端和客户端两部分,使用Socket编程和多线程技术处理通信。服务器负责用户认证、消息路由和好友管理;客户端提供GUI界面,支持用户注册/登录、添加好友和实时聊天。系统实现了文本协议通信,采用文件存储用户数据,包含好友在线状态显示和消息通知功能。虽然简化了安全性和性能处理,但完整展示了即时通讯系统的基本原理和实现方法,可作为学习Java网络编程和GUI开发的参考案例。

1306

循序渐进Socket网络编程(多客户端、信息共享、文件传输)

循序渐进Socket网络编程(多客户端、信息共享、文件传输)   前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据。故把Socket的基础知识总结梳理一遍。 1、TCP/IP协议   既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输。这里就要使用到TCP...

weixin_30410119的博客 282

JAVA中使用网络编程实现客户端之间的对话

tomcat压缩版启动时提示:该catalina_home环境变量没有定义正确的这个环境变量需要运行这个程。 你的jdk是32位的,tomcat是64位的 jdk32位和tomcat64位互不兼容吗? 恩,Tomcat运行需要依赖于JRE 本回答由提问者推荐 怎么tomcat catalina.bat文件中修...

计算机毕业论文源码,学生个人网页制作html源码。贴近用户做网络推广和互联网优化。 318

网络编程——互联网多人聊天系统

写在前面 该篇文章只是介绍性内容,完整的资源(包括代码)在主页资源→互联网多人聊天系统中 目 录 中文摘要 第1章 系统开发基础技术 1.1项目内容介绍 1.2相关技术1 1.3相关技术2 1.4相关技术3 第2章 系统分析 2.1系统需求分析 2.2系统概要设计 2.3系统详细设计 第3章 系统开发 3.1系统开发环境配置 3.2 系统开发 第4章 系统测试 4.1 测试环境 4.2功能测试 4.3测试结果分析 第5章 开发过程的问题及解决方案 ...

看看就好,IT小白 2682

5、Java网络编程—多客户端之间的通信

5、多客户端之间的通信 服务器可以与多个客户端实现通信了,那我们真正的目的是要实现多个客户端之间的通信,使用TCP协议实现的方案是: 客户端的数据包通过服务器中转,发送到另一个客户端,如下图所示: ...

weixin_53330986的博客 627

JAVA网络编程——双用户聊天室实现

双用户聊天室实现实现方案基本说明user1user2代码实现测试拓展——增加user3测试 实现方案 TCP + 多线程 基本说明 user1 user1 实际上是作为服务器端,在本机暴露9999端口,使用accept()函数实现监听,需要先开始user1的程序,再开启user2程序。 user1有类 user1_send 和 user1_listen 分别负责发送和监听。 user2 user2 实际上是作为客户端,使用Socket(“127.0.0.1”,9999)设置目标地址和端口,发送连接请求。 u

Mr.White的博客 2133
上一篇: Java网络编程之服务器与多客户端通信
下一篇: Java网络编程之UDP协议
LemonSnm
博客等级 码龄8年 66粉丝 168原创
评论 22
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值