广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java实现多对多网络通讯的流程
  • 663
分享到

Java实现多对多网络通讯的流程

2024-04-02 19:04:59 663人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

基本流程 客户端发送信息(指定目标客户端)至固定的一个服务端,服务端接收信息进行处理后发送至相应的客户端 通讯核心类 Socket类与流相辅相成,完成通讯。在accept方法返回了

基本流程

客户端发送信息(指定目标客户端)至固定的一个服务端,服务端接收信息进行处理后发送至相应的客户端

在这里插入图片描述

通讯核心类

Socket类与流相辅相成,完成通讯。在accept方法返回了一个Socket对象后,获取socket的输入输出流,就可以接收信息或发送信息了,以一对一为例:

服务端 :


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;


public class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端套接字并指定端口
        ServerSocket server = new ServerSocket(88);
        // 接收创建建立,返回连接创建好后服务器的socket对象
        Socket socket = server.accept();

        InputStreamReader reader = new InputStreamReader(socket.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(reader);

        // 获取请求
        String request = bufferedReader.readLine();
        System.out.println("client say:" + request);

        // 写到输出流传递给客户端
        PrintWriter writer = new PrintWriter(socket.getOutputStream());
        String line = "hello too";
        writer.println(line);
        writer.flush();

        // 关闭处理流的工具、socket套接字、服务套接字
        writer.close();
        bufferedReader.close();
        socket.close();
        server.close();
    }
}

客户端 :


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;


public class Client {
   public static void main(String[] args) throws IOException {
        // 创建socket连接,指明其地址和端口
        Socket socket = new Socket("127.0.0.1", 88);

        // 获取套接字的输出流,输出hello
        PrintWriter writer = new PrintWriter(socket.getOutputStream());
        String readLine = "Hello";
        writer.println(readLine);
        writer.flush();

        // 从套接字的输入流中获取信息
        InputStreamReader reader = new InputStreamReader(socket.getInputStream());
        BufferedReader bufferedReader = new BufferedReader(reader);
        String respond = bufferedReader.readLine();
        System.out.println("server say:" + respond);

        bufferedReader.close();
        writer.close();
        socket.close();
    }
}

运行结果:

在这里插入图片描述

需要注意的是accept方法在没有连接的时候会阻塞,而导致后面的代码无法执行,在接下来的多对多通讯中需要依靠多线程来解决这个问题。

多对多代码实现

为了方便服务端和客户端对信息的处理,解析。首先定义一个消息类,定义属性分别为端口的本地地址,发送的消息内容,发送的目标地址。定义静态方法:将字符串解析为该类实例,处理消息的收发:


import com.alibaba.fastJSON.jsON;
import java.io.Serializable;
import com.alibaba.fastjson.JSON;
import java.io.*;
import java.net.Socket;


public class SocketMessage implements Serializable {

    
    private String key;

    
    private String to;

    
    private String content;

    public String geTKEy() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getTo() {
        return to;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    
    public static void writeTargetMessage(SocketMessage message, Socket socket) throws IOException {
        PrintWriter writer = new PrintWriter(socket.getOutputStream());
        // 统一字符串标准,以便于服务端解析
        writer.println(JSON.toJSONString(message));
        writer.flush();
    }

    
    public static SocketMessage parseSocket(InputStream is) throws Exception {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        String info = reader.readLine();

        return parseSocketByStr(info);
    }


    
    public static SocketMessage parseSocketByStr(String str) {
        SocketMessage socketMessage = null;
        try {
            socketMessage = JSON.parseObject(str, SocketMessage.class);
        } catch (Exception ex) {
            throw new RuntimeException("socket之间通讯不能不使用SocketMessage");
        }
        return socketMessage;
    }

    @Override
    public String toString() {
        // 通过 阿里巴巴 的FastJson 库,将一个对象转换为 字符串 ,统一标准,以便于将字符串解析为该类
        return JSON.toJSONString(this);
    }
}

再单独定义一个服务端的消息处理类,该类用于发送消息至特定的客户端,所以定义两个属性,1.发送的消息,2.目标客户端的套接字:


import java.net.Socket;


public class SocketMessageHandler {

    SocketMessage sm;

    Socket targetSocket;

    public SocketMessageHandler(SocketMessage sm,Socket targetSocket) {
        this.sm = sm;
        this.targetSocket = targetSocket;
    }

    public void setSm(SocketMessage sm) {
        this.sm = sm;
    }

    
    public void send() {

        if (this.sm == null) {
            return;
        }
        try {
            System.out.println(sm.getContent());

            // 发送
            SocketMessage.writeTargetMessage(sm, this.targetSocket);

        } catch ( Exception ex) {
            ex.printStackTrace();
        }
    }
}

接下来进行服务端的定义,我们的服务端需要处理多个客户端的消息,所以要定义一个容器存放客户端地址,在此之前我们已经定义了处理服务端消息的SocketMessageHandler类,因为我们的最终目的是为了处理信息,所以可以直接将SocketMessageHandler类存放至容器。我们用map来存储,而key就是客户端的地址:


import com.issac.task_05.task.msg.SocketMessage;
import com.issac.task_05.task.msg.SocketMessageHandler;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;


public class SocketServer {

	// 存放消息处理器
    private static final Map<String, SocketMessageHandler> clientContainer = new HashMap<>();

    public static void main(String[] args) {

        try {
            ServerSocket ss = new ServerSocket(8888);
            Socket accept;
            while (true) {

                
                accept = ss.accept();
                SocketMessage msg = SocketMessage.parseSocket(accept.getInputStream()); // 获取信息
                System.out.println("客户端建立连接:" + msg.getKey());

                // 建立连接后将客户端地址存入容器
                clientContainer.put(msg.getKey(), new SocketMessageHandler(msg, accept));


                
                new ServerThread(accept, clientContainer).start();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

在这里需要注意ServerSocket类的accept方法,在没有新连接的时候,该方法会阻塞,而之后的代码就无法执行了。我们在客户端与服务端连接成功之后进行消息收发的时候是没有新连接产生的,此时的阻塞导致无法进行通讯,于是乎我们需要再开辟一个线程,进行消息处理。那么我们定义一个继承Thread的消息处理类,将每次连接成功返回的套接字接收,进行信息处理。如此一来,只要有消息的传递该线程就可以进行获取:


import com.issac.task_05.task.msg.SocketMessage;
import com.issac.task_05.task.msg.SocketMessageHandler;

import java.io.InputStream;
import java.net.Socket;
import java.util.Map;


public class ServerThread extends Thread{
    private Socket socket;
    InputStream inputStream;
    Map<String, SocketMessageHandler> clientContainer;

    public ServerThread(Socket socket,Map<String, SocketMessageHandler> clientContainer){
        this.socket = socket;
        this.clientContainer = clientContainer;
    }

    public void run(){
        try{
            while (true){
                // 将输入流中的数据解析为SocketMessage对象
                inputStream = socket.getInputStream();
                SocketMessage msg = SocketMessage.parseSocket(inputStream);
                System.out.println(msg);

                // 在容器中获取目标地址
                SocketMessageHandler socketMessageHandler = clientContainer.get(msg.getTo());

                // 设置需要传输的信息
                socketMessageHandler.setSm(msg);

                // 传输信息
                socketMessageHandler.send();

            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

最后就是客户端了,每个客户端所对应的服务端都相同,在客户端写一个简易的菜单,选择接收或发送消息即可:


import com.issac.task_05.task.msg.SocketMessage;

import java.net.Socket;
import java.util.Scanner;


public class Client {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        Socket s = null;

        try {
            s = new Socket("localhost", 8888);
            // 第一次启动,创建socket,向服务器发送我是谁
            SocketMessage initMsg = getSocketMsg(s.getLocalSocketAddress().toString(), null, null);
            System.out.println("开始与服务器建立连接: " + initMsg.toString());
            SocketMessage.writeTargetMessage(initMsg, s);


            // 开始 循环等待
            while (true) {

                System.out.println("===================menu=====================");
                System.out.println("1:发送消息");
                System.out.println("2:接收消息");

                int choice = scanner.nextInt();

                switch (choice){
                    case 1: // 发送消息
                        String target = input("请输入您要发给谁:");
                        String content = input("请输入您要发送的内容:");
                        System.out.println();

                        SocketMessage afterMsg = getSocketMsg(s.getLocalSocketAddress().toString(), target, content);
                        SocketMessage.writeTargetMessage(afterMsg, s);
                        break;
                    case 2: // 接收并打印消息
                        showRequiredMsg(s);
                        break;
                    default:

                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    
    public static String input(String tip) {
        Scanner input = new Scanner(System.in);
        System.out.println(tip);
        return input.next();
    }

    
    public static SocketMessage getSocketMsg(String localSocketAddress, String to, String content) {
        SocketMessage socketMessage = new SocketMessage();

        // to 为null的时候,说明只是对服务器的初始
        socketMessage.setKey(localSocketAddress.replaceAll("\\/", ""));
        socketMessage.setTo(to);
        socketMessage.setContent(content);

        return socketMessage;
    }

    
    public static void showRequiredMsg(Socket socket) throws Exception {
        SocketMessage socketMessage = SocketMessage.parseSocket(socket.getInputStream());
        String source = socketMessage.getKey();
        String content = socketMessage.getContent();
        System.out.println("接收到来自《"+source+"》的信息:"+content+"\n");
    }
}

运行结果:

在这里插入图片描述
在这里插入图片描述

到此这篇关于Java实现多对多网络通讯的流程的文章就介绍到这了,更多相关Java多对多网络通讯内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java实现多对多网络通讯的流程

本文链接: https://www.lsjlt.com/news/124608.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java实现多对多网络通讯的流程
    基本流程 客户端发送信息(指定目标客户端)至固定的一个服务端,服务端接收信息进行处理后发送至相应的客户端 通讯核心类 Socket类与流相辅相成,完成通讯。在accept方法返回了...
    99+
    2022-11-12
  • 基于Java网络编程和多线程的多对多聊天系统
    目录1.前言2.类图3.代码1.前言 程序实现基于星型结构(服务器接收来自各个客户端发送的信息,然后将信息传递给其他客户端界面并在其他客户端界面显示发送的信息) 2.类图 3.代...
    99+
    2022-11-12
  • Java网络编程实现多线程聊天
    本文实例为大家分享了Java网络编程实现多线程聊天的具体代码,供大家参考,具体内容如下 聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句...
    99+
    2022-11-12
  • c#多进程通讯的实现示例
    目录引言共享内存Windows的MSMQ命名管道匿名管道Channel     IPC     Http  &n...
    99+
    2022-11-13
  • 怎么用php实现多对一通讯录
    随着移动互联网的快速发展,人们使用手机和电脑联系和交流的方式已经越来越多样化。电话、邮件、短信、社交媒体应用等,使得人们可以从各种角度与朋友、家人、同事等联系。然而,这些手段有时解决不了一些需要快速协作和沟通的问题,比如企业内部联系人的管理...
    99+
    2023-05-14
    php
  • 如何用php实现多对一通讯录
    本文小编为大家详细介绍“如何用php实现多对一通讯录”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何用php实现多对一通讯录”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一. 通讯录的基本功能添加联系人:包括...
    99+
    2023-07-05
  • Java网络编程怎么实现多线程聊天
    这篇文章将为大家详细讲解有关Java网络编程怎么实现多线程聊天,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句。...
    99+
    2023-06-20
  • Java网络编程UDP实现多线程在线聊天
    本文实例为大家分享了Java实现多线程在线聊天的具体代码,供大家参考,具体内容如下 上一篇博客通过UDP实现了聊天,但只能单方面发送消息,这次实现了多线程在线聊天,也就是可以双方互发...
    99+
    2022-11-12
  • Java中怎么实现多线程通信
    Java中怎么实现多线程通信,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。概述多线程通信问题,也就是生产者与消费者问题生产者和消费者为两个线程,两个线程在运行过程中交替睡眠,生...
    99+
    2023-06-20
  • Java 异步编程教程:异步编程对于网络通信的响应速度有多大影响?
    随着技术的不断进步,网络通信已经成为了我们日常生活中不可或缺的一部分。在这个信息时代,我们需要更快更高效的网络通信方式,以满足人们对于网络传输速度的需求。而异步编程就是一种能够提高网络通信效率的方式。 在传统的同步编程中,当一个线程执行一...
    99+
    2023-06-25
    异步编程 教程 http
  • Android实现网络多线程文件下载
    实现原理 (1)首先获得下载文件的长度,然后设置本地文件的长度。 (2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。 如:文件的长度为6M,线程数为3,那么...
    99+
    2022-06-06
    多线程 线程 Android
  • Java中的多线程如何实现线程通信
    这篇文章将为大家详细讲解有关Java中的多线程如何实现线程通信,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java多线程中线程间的通信一、使用while方式来实现线程之间的通信packag...
    99+
    2023-05-31
    java 多线程 线程通信
  • java多线程实现交通灯管理系统
    本文实例为大家分享了java多线程实现交通灯管理系统的具体代码,供大家参考,具体内容如下 一. 项目要求 模拟实现十字路口的交通灯管理系统逻辑。详细需求例如以下: 1、异步随机生...
    99+
    2022-11-12
  • Java面向对象编程的多态怎么实现
    本文小编为大家详细介绍“Java面向对象编程的多态怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java面向对象编程的多态怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Java面向对象编程之多态...
    99+
    2023-06-26
  • Java多线程局域网聊天室的实现
    目录1.TCP2.套接字3.C/S架构4.多线程5.服务器客户端局域网聊天室 在学习了一个学期的java以后,觉得java真是博大精深,彻底放弃了因为c++而轻视java的心态,搞了...
    99+
    2022-11-12
  • 计算机网络编程 | 并发服务器代码实现(多进程/多线程)
    欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学...
    99+
    2023-08-18
    计算机网络 多进程 多线程 并发服务器 Linux网络编程 原力计划
  • Qt多线程实现网络发送文件功能
    本文实例为大家分享了Qt多线程实现网络发送文件功能的具体代码,供大家参考,具体内容如下 客户端给服务器发送文件,服务器进行接收文件的简单操作 1. 服务器 1. 创建QTcpServ...
    99+
    2022-11-13
  • C++基于socket多线程实现网络聊天室
    本文实例为大家分享了C++基于socket多线程实现网络聊天室的具体代码,供大家参考,具体内容如下 1. 实现图解 2. 聊天室服务端:TCP_Server_Chat.cpp ...
    99+
    2022-11-12
  • 如何通过Zoho Mail实现网易、腾讯等多邮箱的管理
    如何通过Zoho Mail实现网易、腾讯等多邮箱的管理,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。现在我们一般都会使用多个邮箱来处理工作和个人事物,比如有用于和客户沟通的...
    99+
    2023-06-05
  • 怎么在JAVA项目中实现一个UDP网络通讯功能
    今天就跟大家聊聊有关怎么在JAVA项目中实现一个UDP网络通讯功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体如下:UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用...
    99+
    2023-05-31
    java udp ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作