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

第二十一章 网络通信

计算机网络实现了堕胎计算机间的互联,使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序,这些程序借助于网络协议,相互之间可以交换数据,编写网络应用程序前,首先必须明确网络协议TCP/IP协议是网络应用程序的首选

4a4f2a9ac8e34647ad72104914e9a0fb.png

 网络程序设计基础:

网络程序设计编写始于其他计算机进行通信的程序,java已经将网络程序所需要而定元素封装成不同的类,用户只要床啊金这些类的对象,使用相应的方法即使不举报相关的网络知识,也是可以编写除高质量的网络通信程序的,

 

本章最主要的是TCP和UDP两个部分 他们两主要的区别就是一个是一对一通信 一个是一对多通信 当然两者都有各自的优势和劣势,接下来先讲解 TCP部分

 

TCP程序

TCP程序的通信方式呢 是一对一的 步骤是 先要打开服务器然后客户端连接服务器 先是尝试客户端是否能够接收到信息 如果可以接收到信息的话 这时服务器将会把文件传输给客户端,这样的话 能够保证客户端可以接收到信息 ,劣势呢就是每次都是要这样子 所以效率对比起UDP来说慢下了好多 以下代码将会进行讲解

客户端代码:

import java.io.*;

import java.net.Socket;

import java.util.Scanner;

 

/**

 * Socket客户端

 **/

public class SocketClient {

    public static void main(String[] args) {

        Socket s = null;

        try {

            // 与ip为127.0.0.1、端口为12345的服务端建立连接

            s = new Socket("127.0.0.1", 12345);

 

            // 创建输入流接收服务端发送的消息(字节流)

            InputStream is = s.getInputStream();

            // 将服务端返回的字节流转化为字符流

            InputStreamReader isr = new InputStreamReader(is);

            // 创建字符流读取缓冲区,方便每行读取

            BufferedReader br = new BufferedReader(isr);

 

            // 创建输出流返回消息

            OutputStream os = s.getOutputStream();

            // 创建输出流缓冲

            PrintWriter pw = new PrintWriter(os);

 

            // 创建发送消息的线程

            Runnable rOut = () -> {

                boolean flag = true;

                while (flag) {

                    try {

                        // 接收控制台输入

                        Scanner scan = new Scanner(System.in);

                        String msg = scan.nextLine();

                        // 将输入写入缓冲

                        pw.println(msg);

                        // 将缓冲内的数据推送至服务端并清空缓冲区

                        pw.flush();

                    } catch (Exception e) {

                        flag = false;

                        e.printStackTrace();

                    }

                }

            };

 

            // 创建接收消息的线程

            Runnable rIn = () -> {

                boolean flag = true;

                while (flag) {

                    try {

                        // 逐行读取服务端返回的消息并打印

                        String str = br.readLine();

                        System.out.println("服务端的消息:" + str);

                    } catch (IOException e) {

                        flag = false;

                        e.printStackTrace();

                    }

                }

            };

 

            // 启动两个线程

            Thread tOut = new Thread(rOut);

            Thread tIn = new Thread(rIn);

            tOut.start();

            tIn.start();

        }catch (IOException e) {

            try {

                // 释放资源

                s.close();

            } catch (Exception exception) {

                exception.printStackTrace();

            }

            e.printStackTrace();

        }

    }

}

服务端代码:


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
 
/**
 * Socket服务端
 **/
public class SocketServer {
    public static void main(String[] args) {
        ServerSocket ss = null;
        Socket s = null;
        try {
            // 创建监听端口为12345的Socket服务端
            ss = new ServerSocket(12345);
            System.out.println("服务端Socket服务已建立,等待客户端连接...");
            // 通过ss.accept()开始持续监听12345端口,当有连接时获取收到的包装成Socket的客户端对象
            s = ss.accept();
            // 获取客户端的IP地址和端口号
            String ip = s.getInetAddress().getHostAddress();
            int port = s.getPort();
            System.out.println("服务端与 " + ip + ":" + port + " 已建立连接");
 
            // 创建输入流接收客户端发送的消息(字节流)
            InputStream is = s.getInputStream();
            // 将客户端发送的字节流转化为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 创建字符流读取缓冲区,方便每行读取
            BufferedReader br = new BufferedReader(isr);
 
            // 创建输出流返回消息
            OutputStream os = s.getOutputStream();
            // 创建输出流缓冲
            PrintWriter pw = new PrintWriter(os);
 
            // 创建接受信息的线程
            Runnable rIn = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 逐行读取客户端发送的消息并打印
                        String str = br.readLine();
                        System.out.println("客户端的消息:" + str);
                    } catch (IOException e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };
 
            // 创建发送消息的线程
            Runnable rOut = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 接收控制台输入
                        Scanner scan = new Scanner(System.in);
                        String msg = scan.nextLine();
                        // 将输入写入缓冲
                        pw.println(msg);
                        // 将缓冲内的数据推送至客户端并清空缓冲区
                        pw.flush();
                    } catch (Exception e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };
 
            // 开启两个线程
            Thread tIn = new Thread(rIn);
            Thread tOut = new Thread(rOut);
            tIn.start();
            tOut.start();
        } catch (IOException e) {
            try {
                // 释放资源
                ss.close();
                s.close();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

运行结果:

b65e0cf343ba40f88f74718fbc823b85.png

 接下来讲解UDP程序

UDP程序

UDP程序跟TCP程序不同的地方呢 TCP通信是一对一通信 如果要一下通知好多个人的话 就需要一个一个来通信 所以这时将会需要UDP了 UDP的优势就在于效率高 但是不稳定的地方呢 就是效率高但是不一定每个人都能看到 就像老师在台上讲课 总有一些学生会在台下玩手机 或者带耳机 不一定每一个人都能够接受得到 这就是UDP的不稳定的地方 ,接下来使用代码来讲解:

广播类代码如下:

 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
//广播  先运行
public class Notification  extends Thread{
    String weather = "节目预报:八点有大型晚会,请收听";//发送消息
    int port = 9898;//端口号
    InetAddress iaddress = null;
    MulticastSocket socket = null;//多点广播套接字
    
    Notification(){
        try {
            iaddress = InetAddress.getByName("224.255.10.0");//地址
            socket = new MulticastSocket(port);//实例化多点广播套接字
            socket.setTimeToLive(1);//指定发送范围是本地网络
            socket.joinGroup(iaddress);//加入广播组
        }catch(IOException e){
            e.printStackTrace();//输出异常信息
        }
    
    }
    public void run(){//run方法
        while(true) {
            DatagramPacket packet = null;//数据包
            byte data[]=weather.getBytes();//字符串消息的字节数组
            packet =  new  DatagramPacket(data,data.length,iaddress,port);//将数据打包
            System.out.println(weather);//控制台打印消息
            try {
                socket.send(packet);//发送数据
                sleep(3000);//让线程休眠3000毫秒
            }catch(IOException e){
                e.printStackTrace();
            }catch(InterruptedException e) {
                e.printStackTrace();
            }
        }    
            }
    public static void main(String[]args) {
        Notification w =new Notification();
        w.start();//启动线程
    }
}

接收类代码如下:

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.InetAddress;

import java.net.MulticastSocket;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.WindowConstants;

//接收 后运行

public class Receive extends JFrame implements Runnable, ActionListener {

 int port ;//端口

 InetAddress group =null;//广播组地址

 MulticastSocket socket = null;//多点广播套接字对象

 JButton inceBtn = new JButton("开始接收");

 JButton stopBtn = new JButton("停止接收");

 JTextArea inceAr = new JTextArea(10,10);//显示接收广播的文本域

 JTextArea inced = new JTextArea(10,10);

 Thread thread ;

 boolean stop = false;//定制接受信息状态

 

 public Receive () {

  setTitle("广播数据包");

  setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

  thread = new Thread(this);

  inceBtn.addActionListener(this);//绑定按钮ince的单击事件

  stopBtn.addActionListener(this);//绑定按钮stop的单击事件

  inceAr.setForeground(Color.blue);//指定文本域中文字的颜色

  

  JPanel north = new JPanel();

  north.add(inceBtn);//将按钮添加到面板north上

  north.add(stopBtn);

  add(north,BorderLayout.NORTH);//将north放置在窗体的上部

  JPanel center = new JPanel();//创建面板对象center

  center.setLayout(new GridLayout(1,2));//设置面板布局

  center.add(inceAr);//将文本域添加到面板上

  center.add(inced);

  add(center,BorderLayout.CENTER);//设置面板的布局

  validate();//刷新

  port =9898;//设置端口号

  try {

   group = InetAddress.getByName("224.255.10.0");//指定接收地址

   socket = new MulticastSocket(port);//绑定多点广播套接字

   socket.joinGroup(group);//加入广播组

  }catch(IOException e){

   e.printStackTrace();//输出异常信息

  }

  setBounds(100,50,360,380);//设置布局

  setVisible(true);//将窗体设置为显示状态

 }

 public void run() {//run方法

  while (!stop) {

   byte data[] = new byte[1024];//创建缓存字节数组

   DatagramPacket packet = null;

   packet = new DatagramPacket(data,data.length,group,port);//待接收的数据包

   try {

    socket.receive(packet);//接收数据包

    //获取数据包中的内容

    String message = new String(packet.getData(),0,packet.getLength());

    inceAr.setText("正在接收的内容:\n"+message);//将接受内容显示在文本域中

    inced.append(message+"\n");//每条信息为一行

   }catch(IOException e ) {

    e.printStackTrace();//输出异常信息

   }

   

  }

 }

 public void actionPerformed(ActionEvent e) {//单机按钮ince出发时间

  if(e.getSource()==inceBtn) {

   inceBtn.setBackground(Color.red);//设置按钮颜色

   stopBtn.setBackground(Color.yellow);

   if(!(thread.isAlive())) {//如线程不处于“新建状态”

    thread = new Thread(this);//实例化Thread对象

   }

   thread.start();//启动线程

   stop = false;//开始接受信息

  }

  if(e.getSource()== stopBtn) {//单机按钮stop出发时间

   inceBtn.setBackground(Color.yellow);//设置按钮亚瑟

   stopBtn.setBackground(Color.red);

   stop = true;//停止接收信息

  }

 }

 public static void main(String[]args) {

  Receive rec = new Receive();

  rec.setSize(460,200);

 }

}

运行结果:e42f5062ade343edb1e76b0429cdc5ac.png

 

相关文章:

第二十一章 网络通信

计算机网络实现了堕胎计算机间的互联,使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序,这些程序借助于网络协议,相互之间可以交换数据,编写网络应用程序前,首先必须明确网络协议…...

【漏洞复现】万户协同办公平台ezoffice wpsservlet接口存在任意文件上传漏洞 附POC

漏洞描述 万户ezOFFICE集团版协同平台以工作流程、知识管理、沟通交流和辅助办公四大核心应用 万户ezOFFICE协同管理平台是一个综合信息基础应用平台。 万户协同办公平台ezoffice wpsservlet接口存在任意文件上传漏洞。 免责声明 技术文章仅供参考,任何个人和组织使用网络应…...

【uniapp】小程序中input输入框的placeholder-class不生效解决办法

问题描述 uniapp微信小程序&#xff0c;使用input组件时&#xff0c;想要改变提示词 placeholder 的样式&#xff0c;但是使用placeholder-class 改变不了 如下&#xff1a; <input type"text" placeholder"搜索" placeholder-class"placeholde…...

SimplePIR——目前最快单服务器匿踪查询方案

一、介绍 这篇论文旨在实现高效的单服务器隐私信息检索&#xff08;PIR&#xff09;方案&#xff0c;以解决在保护用户隐私的同时快速检索数据库的问题。为了实现这一目标&#xff0c;论文提出了两种新的PIR方案&#xff1a;SimplePIR和DoublePIR。这两种方案的实现基于学习与错…...

Spring Boot中使用Swagger

1. 启用Swagger 1.1 启用注解扫描和文档接口 直接在POM文件引入依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> </dependency>1.2 启动swagger-u…...

uniapp实战 —— 竖排多级分类展示

效果预览 完整范例代码 页面 src\pages\category\category.vue <script setup lang"ts"> import { getCategoryTopAPI } from /apis/category import type { CategoryTopItem } from /types/category import { onLoad } from dcloudio/uni-app import { compu…...

SAP UI5 walkthrough step6 Modules

在SAPUI5 中&#xff0c;资源通常用作Modules&#xff0c;这个我们将用Message Toast 来实现告警功能 修改controller.js webapp/controller/App.controller.js sap.ui.define(["sap/ui/core/mvc/Controller","sap/m/MessageToast" ], (Controller, Mes…...

时间相关类

内容 JDK7时间相关类JDK8时间相关类 第一章 Date类 1.1 Date概述 java.util.Date类 表示特定的瞬间&#xff0c;精确到毫秒。 继续查阅Date类的描述&#xff0c;发现Date拥有多个构造函数&#xff0c;只是部分已经过时&#xff0c;我们重点看以下两个构造函数 public Dat…...

数据库事务:保障数据一致性的基石

目录 1. 什么是数据库事务&#xff1f; 1.1 ACID特性解析 2. 事务的实现与控制 2.1 事务的开始和结束 2.2 事务的隔离级别 3. 并发控制与事务管理 3.1 并发控制的挑战 3.2 锁和并发控制算法 4. 最佳实践与性能优化 4.1 事务的划分 4.2 批处理操作 5. 事务的未来发展…...

自动化操作脚本

文章目录 vbsopenCV pyautogui vbs SSH连接并执行指令操作 Dim WshShell Set WshShellWScript.CreateObject("WScript.Shell") WshShell.Run "cmd.exe" WScript.Sleep 1000 WshShell.SendKeys "ssh xcmg10.27.40.103" WshShell.SendKeys &qu…...

MVC、MVP、MVVM模式的区别

前言&#xff1a;这三个表现层框架设计模式是依次进化而形成MVC—>MVP—>MVVM。在以前传统的开发模式当中即MVC模式&#xff0c;前端人员只负责Model&#xff08;数据库&#xff09;、 View&#xff08;视图&#xff09;和 Controller /Presenter/ViewModel&#xff08;控…...

【Vue】日常错误总结(持续更新)

日常遇到的小问题汇总, 内容小篇幅少的就全放这里了, 内容多的会在Vue专栏单独分享~ 目录 【Q】 el-form-item值为 null 或 undefined显示““ 【Q】dialog内组件数据刷新总是延迟慢一拍 问题背景描述 解决方案 代码简单模拟 JS 【Q】el-input 不能输入的解决办法 方法…...

java多线程(常用方法、实现方式、线程安全问题、生命周期、线程池)

多线程相关的三组概念 程序和进程 程序&#xff08;program&#xff09;&#xff1a;一个固定的运行逻辑和数据的集合&#xff0c;是一个静态的状态&#xff0c;一般存储在硬盘中。简单来说就是我们编写的代码 进程&#xff08;process&#xff09;&#xff1a;一个正在运行的…...

Day05 linux高级系统设计 - 管道

复制文件描述符 dup函数 作用&#xff1a; 文件描述符复制 语法&#xff1a; #include <unistd.h> int dup (int oldfd); 参数&#xff1a; 所需复制得文件描述符 返回值&#xff1a; 复制到的文件描述符 功能&#xff1a; 从文件描述符表中&#xff0c;找一个最小…...

低代码:美味膳食或垃圾食品?

一、什么是低代码 低代码是一种开发方法&#xff0c;通过可视化界面和少量的编码&#xff0c;使开发者能够快速构建应用程序。它的目标是提高开发效率、降低开发成本&#xff0c;并支持快速迭代和敏捷开发。 二、低代码的优缺点 低代码开发具有以下优点&#xff1a; 快速开…...

免费网页抓取工具大全【附下载和工具使用教程】

在当今信息爆炸的时代&#xff0c;获取准确而丰富的数据对于企业决策和个人研究至关重要。而网页抓取工具作为一种高效获取互联网数据的方式&#xff0c;正逐渐成为大家解决数据需求的得力助手。本文将深入探讨网页抓取工具的种类&#xff0c;并为大家提供简单实用的页面采集教…...

Leetcode 39 组合总和

题意理解&#xff1a; 一个 无重复元素 的整数数组 candidates 和一个目标整数 target 从candidates 取数字&#xff0c;使其和 target &#xff0c;有多少种组合&#xff08;candidates 中的 同一个 数字可以 无限制重复被选取&#xff09; 这道题和之前一道组合的区别&am…...

Windows下使用AndroidStudio及CMake编译Android可执行程序或静态库动态库

Windows下使用AndroidStudio及CMake编译Android可执行程序或静态库动态库 文章目录 Windows下使用AndroidStudio及CMake编译Android可执行程序或静态库动态库一、前言二、编译环境三、示例C/CPP程序1、总体工程结构2、示例代码3、CMakeLists.txt&#xff08;重要&#xff09;4、…...

MySQL七 | 存储引擎

目录 存储引擎 存储引擎特点 存储引擎选择 Innodb与MyISAM区别 存储引擎 默认存储引擎:InnoDB show engines;#展示当前数据库支持的存储引擎 存储引擎特点 特点InnoDBMyISAMMemory存储限制64TB有有事务安全支持--锁机制行锁表锁表锁Btree锁支持支持 支持 Hash索引--支…...

网上下载的pdf文件,为什么不能复制文字?

不知道大家有没有到过这种情况&#xff1f;在网上下载的PDF文件打开之后&#xff0c;发现选中文字之后无法复制。甚至其他功能也都无法使用&#xff0c;这是怎么回事&#xff1f;该怎么办&#xff1f; 当我们发现文件打开之后&#xff0c;编辑功能无法使用&#xff0c;很可能是…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...