26-网络通信

网络通信

什么是网络编程?
可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。
java.net.包下提供了网络编程的解决方案!
基本的通信架构有2种形式:CS架构( Client客户端/Server服务端 ) 、 BS架构(Browser浏览器/Server服务端)。

image-20230811093617412

image-20230811093708272

我们java的重点是开发BS架构
无论是CS架构,还是BS架构的软件都必须依赖网络编程

网络通信的三要素

  1. IP地址 设备在网络中的地址,是唯一的标识。
  2. 端口 应用程序在设备中唯一的标识
  3. 协议 连接和数据在网络中传输的规则。

IP地址

IP(Internet Protocol):全称”互联网协议地址”,是分配给上网设备的唯一标志。
IP地址有两种形式:IPv4、IPv6

IPV4

image-20230811094428007

IPV6

32为的IP地址根本不够为我们如此多的IP的地址进行编号,所以演变出了IPV6地址
IPv6:共128位,号称可以为地球每一粒沙子编号。
IPv6分成8段表示,每段每四位编码成一个十六进制位表示, 数之间用冒号(:)分开。
image-20230811095044814

IP域名

域名就是最后也要转化为IP的
image-20230811095232838

特殊IP

公网IP,内网IP
公网IP:是可以连接互联网的IP地址;内网IP:也叫局域网IP,只能组织机构内部使用。
192.168. 开头的就是常见的局域网地址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用。
特殊IP地址:非常重要
127.0.0.1、localhost:代表本机IP,只会寻找当前所在的主机。
IP常用命令:
ipconfig:查看本机IP地址。
ping IP地址:检查网络是否连通。

InerAddress命令
名称说明
public static InetAddress getLocalHost()获取本机IP,会以一个inetAddress的对象返回
public static InetAddress getByName(String host)根据ip地址或者域名,返回一个inetAdress对象
public String getHostName()获取该ip地址对象对应的主机名。
public String getHostAddress()获取该ip地址对象中的ip地址信息。
public boolean isReachable(int timeout)在指定毫秒内,判断主机与该ip对应的主机是否能连通
举例
    public static void main(String[] args) {try {InetAddress ia = InetAddress.getLocalHost();  //获取本机IPInetAddress bd = InetAddress.getByName("www.baidu.com");  //获取这个网址的ipSystem.out.println(ia);  //输出这个本机ip的主机System.out.println(ia.getHostName());  //输出这个本机ip的名字System.out.println(ia.getHostAddress()); //输出这个本机ip的地址System.out.println(bd.isReachable(1000)); //判断baidu的主机和本机是否能够在1000ms内进行连接成功} catch (Exception e) {e.printStackTrace();}}输出结果
DESKTOP-ROKA7MJ/111.111.111.1 (这个本机ip我已经修改了,防止自己的ip泄露,这里随便编了一个,为了能够更好的展示结果)
DESKTOP-ROKA7MJ
111.111.111.1
www.baidu.com/180.101.50.188
true

端口号

端口
标记正在计算机设备上运行的应用程序的,被规定为一个 16 位的二进制,范围是 0~65535。
分类
周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用 80,FTP占用21)
注册端口:1024~49151,分配给用户进程或某些应用程序。
动态端口:49152到65535,之所以称为动态端口,是因为它 一般不固定分配某种进程,而是动态分配。
注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错。

协议

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。
开放式网络互联标准:OSI网络参考模型
OSI网络参考模型:全球网络互联标准。
TCP/IP 网络模型:事实上的国际标准。(大四的课程, 进行网络通信)

OSI网络参考模型TCP/IP网络模型各层对应面向操作
应用层应用层HTTP、FTP、SMTP…应用程序需要关注的:浏览器,邮箱。程序员一般在这一层开发
表示层应用层HTTP、FTP、SMTP…应用程序需要关注的:浏览器,邮箱。程序员一般在这一层开发
会话层应用层HTTP、FTP、SMTP…应用程序需要关注的:浏览器,邮箱。程序员一般在这一层开发
传输层传输层UDP、TCP…选择使用的TCP , UDP协议
网络层网络层IP…封装源和目标IP
数据链路层数据链路层+ 物理比特流…物理设备中传输
物理层数据链路层+ 物理比特流…比特流…

UDP(User Datagram Protocol):用户数据报协议; TCP(Transmission Control Protocol) :传输控制协议。

UDP协议

特点:无连接、不可靠通信。
不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内)等。
发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的 。
语音童话,还有视频直播我们可以用这个UDP通信,因为数据的丢失对这个影响不大

TCP协议

特点:面向连接、可靠通信。
TCP的最终目的:要保证在不可靠的信道上实现可靠的传输。
TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

image-20230811105551312

image-20230811105831833

image-20230811105854535

UDP通信的快速入门

常用方法

UDP通信
特点:无连接、不可靠通信。
不事先建立连接;发送端每次把要发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包,发出去就不管了。
Java提供了一个java.net.DatagramSocket类来实现UDP通信。
DatagramSocket: 用于创建客户端、服务端

构造器说明
public DatagramSocket()创建客户端的Socket对象, 系统会随机分配一个端口号。
public DatagramSocket(int port)创建服务端的Socket对象, 并指定端口号
方法说明
public void send(DatagramPacketdp)发送数据包
public void receive(DatagramPacket p)使用数据包接收数据

DatagramPacket:创建数据包

构造器说明
public DatagramPacket(byte[] buf, int length, InetAddress address, int port)创建发出去的数据包对象
public DatagramPacket(byte[] buf, int length)创建用来接收数据的数据包
方法说明
public int getLength()获取数据包,实际接收到的字节个数

一发一收

创建一个客户端对象

    public static void main(String[] args) throws Exception {//1. 创建客户端对象,发数据的人DatagramSocket ds = new DatagramSocket();//2 创建数据包对象封装要发出去的数据(创建一个韭菜盒子)  //参数一:封装要发出去的数据//参数二,发出去的数据大小,字节个数//参数三:服务端的IP地址// 参数四: 服务端程序的端口byte[] bytes = "我爱你,你爱我,蜜雪冰城甜蜜蜜".getBytes();DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);ds.send(dp);System.out.println("客户端数据发送完毕");ds.close(); //释放资源}

创建一个服务端对象,注册端口

    public static void main(String[] args) throws Exception {//创建一个服务端对象,注册端口System.out.println("------------");DatagramSocket ds = new DatagramSocket(6666);//创建一个数据包对象,用于接受数据byte [] bytes = new byte[1024*64]; //一个数据包最大不能超过64kb,所以我们接收的时候最好用最大的,防止接收不完DatagramPacket dp = new DatagramPacket(bytes,bytes.length);ds.receive(dp);//读取多少就倒出多少String s = new String(bytes,0,dp.getLength());System.out.println(s);}

多发多收

客户端.可以多次运行

        Scanner input  = new Scanner(System.in);while (true) {System.out.println("请说");String msg = input.nextLine();//退出这个循环if(msg.equals("end")){System.out.println("退出成功,欢迎下次使用");ds.close(); //释放资源break;}byte[] bytes = msg.getBytes();DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);ds.send(dp);System.out.println("客户端数据发送完毕");}

服务端没有必要关闭

        DatagramSocket ds = new DatagramSocket(6666);byte [] bytes = new byte[1024*64]; //一个数据包最大不能超过64kb,所以我们接收的时候最好用最大的,防止接收不完while (true) {System.out.println("------------");DatagramPacket dp = new DatagramPacket(bytes,bytes.length);ds.receive(dp);//读取多少就倒出多少String s = new String(bytes,0,dp.getLength());System.out.println(s);}

TCP通信

一定要注意前后服务端和客户端要一一对应,否则就容易出错

特点:面向连接、可靠通信。
通信双方事先会采用“三次握手”方式建立可靠连接,实现端到端的通信;底层能保证数据成功传给服务端。
Java提供了一个java.net.Socket类来实现TCP通信。

image-20230811120040094

TCP通信之-客户端开发

客户端程序就是通过java.net包下的Socket类来实现的。

常用方法

构造器说明
public Socket(String host , int port)根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket
方法说明
public OutputStream getOutputStream()获得字节输出流对象
public InputStream getInputStream()获得字节输入流对象

TCP通信之-服务端开发

服务端是通过java.net包下的ServerSocket类来实现的。

构造器说明
public ServerSocket(int port)为服务端程序注册端口
方法说明
public Socket accept()阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象。

举例

单发单收
服务端, 从外读input

 //服务端的开发ServerSocket serverSocket = new ServerSocket(8888);//使用servesocket对象,调用accept[t方法,等待客户端的连接请求Socket accept = serverSocket.accept();//从socket通信管道中获取一个字节输入流InputStream is = accept.getInputStream();DataInputStream dis = new DataInputStream(is);//读取数据System.out.println(dis.readUTF());dis.close();serverSocket.close();

客户端,往外写 output

//创建socker对象,并同时请求与服务器程序的连接Socket socket = new Socket(InetAddress.getLocalHost(),8888);//从cocket通信管道中得到一个字节输出流,用来发数据给服务端程序OutputStream os = socket.getOutputStream();//BufferedOutputStream bos = new BufferedOutputStream(os);//把低级的字节输出流,包装成数据输出流DataOutputStream dos = new DataOutputStream(os);dos.writeUTF("我喜欢你");dos.close();socket.close();

多发多收
服务端, 从外读 input

//服务端的开发ServerSocket serverSocket = new ServerSocket(8888);Socket accept = serverSocket.accept();//使用servesocket对象,调用accept[t方法,等待客户端的连接请求//从socket通信管道中的大奥一个字节输入流InputStream is = accept.getInputStream();DataInputStream dis = new DataInputStream(is);while (true) {System.out.println("------------");//读取数据System.out.println(dis.readUTF());}

客户端, 往外写output

        //创建socker对象,并同时请求与服务器程序的连接Socket socket = new Socket(InetAddress.getLocalHost(),8888);Scanner input = new Scanner(System.in);OutputStream os = socket.getOutputStream();//BufferedOutputStream bos = new BufferedOutputStream(os);//把低级的字节输出流,包装成数据输出流DataOutputStream dos = new DataOutputStream(os);while (true) {//从cocket通信管道中得到一个字节输出流,用来发数据给服务端程序String msg = input.nextLine();if(msg.equals("end")){System.out.println("退出客户端");dos.close();socket.close();break;}dos.writeUTF(msg);dos.flush();System.out.println("写入成功");}

如果我们这个客户端挂了,那么服务端也会挂

TCP通信,支持与多个客户端同时通信

目前我们开发的服务端程序,是否可以支持与多个客户端同时通信 ?
不可以的。
因为服务端现在只有一个主线程,只能处理一个客户端的消息。
UDP不需要进行连接,只需要进行发送数据包就好了
image-20230811124405412
所以我们要又多线程来实现多个客户端进行通信
服务端,创建多线程

        ServerSocket serverSocket = new ServerSocket(8888);System.out.println("服务器启动");while (true) {Socket accept = serverSocket.accept();System.out.println("有人上线了,地址是"+accept.getRemoteSocketAddress() );new TCPThread(accept).start();}

线程对象

public class TCPThread extends Thread{private Socket socket;public TCPThread(Socket socket){this.socket=socket;}@Overridepublic void run(){try {InputStream is = socket.getInputStream();DataInputStream dis = new DataInputStream(is);while (true) {//读取数据,防止服务端关闭这里崩溃try {System.out.println(dis.readUTF());System.out.println(socket.getRemoteSocketAddress()+"输入了数据:");} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress()+"关闭");socket.close();dis.close();break;}}} catch (Exception e) {e.printStackTrace();}}
}

客户端

        //创建socker对象,并同时请求与服务器程序的连接Socket socket = new Socket(InetAddress.getLocalHost(),8888);Scanner input = new Scanner(System.in);OutputStream os = socket.getOutputStream();//BufferedOutputStream bos = new BufferedOutputStream(os);//把低级的字节输出流,包装成数据输出流DataOutputStream dos = new DataOutputStream(os);while (true) {//从cocket通信管道中得到一个字节输出流,用来发数据给服务端程序String msg = input.nextLine();if(msg.equals("end")){System.out.println("退出客户端");dos.close();socket.close();break;}dos.writeUTF(msg);dos.flush();System.out.println("写入成功");}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/148477.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习:基于长短时记忆网络LSTM实现情感分析

目录 1 LSTM网络介绍 1.1 LSTM概述 1.2 LSTM网络结构 1.3 LSTM门机制 1.4 双向LSTM 2 Pytorch LSTM输入输出 2.1 LSTM参数 2.2 LSTM输入 2.3 LSTM输出 2.4 隐藏层状态初始化 3 基于LSTM实现情感分析 3.1 情感分析介绍 3.2 数据集介绍 3.3 基于pytorch的代码实现 3…

Ventoy万能U盘安装系统,支持任何的操作系统安装

Ventoy万能U盘安装系统,支持任何的操作系统安装: Download . VentoyVentoy is an open source tool to create bootable USB drive for ISO files. With ventoy, you dont need to format the disk again and again, you just need to copy the iso fil…

LLMs 用强化学习进行微调 RLHF: Fine-tuning with reinforcement learning

让我们把一切都整合在一起,看看您将如何在强化学习过程中使用奖励模型来更新LLM的权重,并生成与人对齐的模型。请记住,您希望从已经在您感兴趣的任务上表现良好的模型开始。您将努力使指导发现您的LLM对齐。首先,您将从提示数据集…

数据结构 2.1 线性表的定义和基本操作

数据结构三要素——逻辑结构、数据的运算、存储结构(物理结构) 线性表的逻辑结构 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列,其中n为表长,当n0时,线性表是一个空表。 每个数…

亲,您的假期余额已经严重不足了......

引言 大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。 转眼八天长假已经接近尾声了,今天来总结一下大家的假期,聊一聊假期关于学习的看法,并预估一下大家节后大家上班时的样子。 1.放假前一天 即将迎来八天…

『力扣每日一题12』:只出现一次的数字

一、题目 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。 示例 1 : 输入&…

QQ怎么上传大于1G的视频啊?视频压缩这样做

当我们想要在QQ上分享一段大容量的视频时,往往会因为超过1G的限制而感到无助。不过,不用担心,今天我们将为你介绍三种可以压缩视频大小的方法,一起来看看吧~ 一、嗨格式压缩大师 嗨格式压缩大师是一款专业的视频压缩软件&#xf…

【Excel】快速提取某个符号前面的数据内容

【问题描述】 在使用excel整理数据过程中,经常与需要调整数据后,进行使用。 例如凭证导出后,科目列是包含科目编码和科目名称的。 但由于要将数据复制到其他的导入模板上使用,对应的模板只需要科目编码,不需要科目名称…

Spring 原理

它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 1 Spring 特点 轻量级控制反转面向切面容器框架集合 2 Spring 核心组件 3 Spring 常用模块 4 Spring 主要包 5 Spring 常用注解 bean…

Springboot学习笔记——1

Springboot学习笔记——1 一、快速上手Springboot1.1、Springboot入门程序开发1.1.1、IDEA创建Springboot项目1.1.2、官网创建Springboot项目1.1.3、阿里云创建Springboot项目1.1.4、手工制作Springboot项目 1.2、隐藏文件或文件夹1.3、入门案例解析1.3.1、parent1.3.2、starte…

侯捷 C++ STL标准库和泛型编程 —— 9 STL周围

最后一篇,完结辽!😋 9 STL周围 9.1 万用Hash Function Hash Function的常规写法:其中 hash_val 就是万用Hash Function class CustumerHash { public:size_t operator()(const Customer& c) const{ return hash_val(c.fna…

x64内核实验2-段机制的变化

x64内核实验2-段机制的变化 ia-32e模式简介 x86下的段描述符结构图如下 在x86环境下段描述符主要分为3个部分的内容:base、limit、attribute,而到了64位环境下段的限制越来越少,主要体现在base和limit已经不再使用而是直接置空&#xff0…

进程调度算法之先来先服务(FCFS),短作业优先(SJF)以及高响应比优先(HRRN)

1.先来先服务(FCFS) first come first service 1.算法思想 主要从“公平”的角度考虑(类似于我们生活中排队买东西的例子) 2.算法规则 按照作业/进程到达的先后顺序进行服务。 3.用于作业/进程调度 用于作业调度时,考虑的是哪个作业先…

商业智能系统的主要功能包括数据仓库、数据ETL、数据统计输出、分析功能

ETL服务内容包含: 数据迁移数据合并数据同步数据交换数据联邦数据仓库

Scala第十一章节

Scala第十一章节 1.模式匹配 2. Option 类型 3.偏函数 4.正则表达式 5.异常处理 6.提取器 7.案例:随机职业 scala总目录 文档资料下载

Boost程序库完全开发指南:1.1-C++基础知识点梳理

主要整理了N多年前(2010年)学习C的时候开始总结的知识点,好长时间不写C代码了,现在LLM量化和推理需要重新学习C编程,看来出来混迟早要还的。 1.shared_ptr 解析:shared_ptr是一种计数指针,当引…

U盘里文件损坏无法打开怎么恢复?

U盘,全称为USB闪存盘,是一种体积小巧、传输数据速度快的便携式存储设备。由于其出色的便捷性和高效性,U盘在各个工作领域和日常生活中得到了广泛应用,赢得了消费者的普遍好评。然而,使用U盘的过程中也可能会面临数据损…

Redis的java客户端-RedisTemplate光速入门

一.创建springboot项目 二.引入2个依赖 <!-- redis依赖-->这个已经引入了&#xff0c;因为创建的时候勾选了<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><…

Sublime Text 4 for Mac激活下载

Sublime Text for Mac是一款适用于Mac平台的文本编辑器。它具有快速的性能和丰富的功能&#xff0c;可以帮助用户快速进行代码编写和文本编辑。 软件下载&#xff1a;Sublime Text 4 for Mac激活下载 该软件具有直观的界面和强大的功能&#xff0c;包括多行选择、代码折叠、自动…

【项目开发 | C语言项目 | C语言病人管理系统】

该项目旨在为医院或其他医疗机构提供一个简易的病人信息管理工具。用户可以通过命令行界面进行病人信息的增、删、查和改操作&#xff0c;并将数据持久化存储在txt文件中。 一&#xff0c;开发环境需求 操作系统 &#xff1a;Windows, Linux 开发环境工具 &#xff1a;Qt, VSC…