JAVASE进阶:网络编程(编程实现TCP、UDP传输)

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习
🌌上期文章:JAVASE进阶:高级写法——方法引用(Mybatis-Plus必学前置知识)
📚订阅专栏:JAVASE进阶
希望文章对你们有所帮助

其实我认为javase中的File流、I/O流(字节流、字符流)等都是很重要的,但是内容很多就没有具体去做总结了,不过这里总结的网络编程中也会用到I/O流中的不少思想,大家可以边学习网络编程边了解I/O流编程,对于I/O流大家需要自行去系统学习或回顾。

网络编程(编程实现TCP、UDP传输)

  • 网络编程介绍
  • 网络编程三要素
    • 三要素——IP
      • ipv4的一些细节
      • InetAddress类的使用
    • 三要素——端口号
    • 三要素——协议
  • UDP协议编程
    • 发送数据
    • 接收数据
  • TCP协议编程
    • 发送数据
    • 接收数据
  • 三次握手和四次挥手

网络编程介绍

网络编程就是在网络通信协议下,不同计算机上运行的程序,进行的数据传输。java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。

常见的软件架构有两种,即B/S架构(浏览器/服务器)和C/S架构(客户端/服务器)。
B/S架构无需开发客户端,只需要页面+服务端,用户不需要下载,打开浏览器就能使用,但若应用过大, 用户体验就会受到影响。
C/S架构的画面可以做的更精美,用户体验更好,但需要开发客户端,也需要开发服务端,且用户时不时的要更新。

网络编程三要素

IP:设备在网络中的地址,是唯一的标识
端口号:应用程序在设备中唯一的标识
协议:数据在网络中传输的规则,常见协议有UDP、TCP、http、https、ftp

三要素——IP

IP全称Internet Protocol,是互联网协议地址,也称IP地址,是分配给上网设备的数字标签,常见的IP分为ipv4和ipv6。

1、ipv4:采用32位地址长度,分为4组,采用点分十进制表示法,最多只有2^32,目前已经分配完毕

2、ipv6:采用128位地址长度,分为8组,采用冒分十六进制表示法,如果计算出的十六进制表示形式中间有多个连续的0,就可以接着采用0位压缩表示法(有一些计网的基础,看名字都挺容易理解的,如果有点模糊可以自行去查阅),最多有2^128个IP,可以为地球上的每一粒沙子分配IP。

ipv4的一些细节

实际上ipv6还没有普及,而ipv4明明已经分配完,但是我们还是主要使用了ipv4。

ipv4的地址可以分为公网地址(万维网用)和私有地址(局域网用),192.168.0.0-192.168.255.255是私有地址的范围。

localhost:127.0.0.1,是回送地址或本地回环地址,只会寻找当地所在本机。

考虑一个问题:若192.168.177.130是我电脑的IP,那么这个IP和127.0.0.1是否一致
答案:不一致,因为不同的局域网分配给我的IP是不一致的,所以平时写demo最好用127.0.0.1或localhost

常用cmd命令:

ipconfig:查看本地ip地址
ping:检查网络是否连通

InetAddress类的使用

InetAddress底层分别有针对ipv4网络和ipv6网络的,InetAddress本身没有构造方法,需要使用它的静态方法getByName去获取到对象,这个方法的底层就会判断我们的ip使用是ipv4还是ipv6的。
其基本使用代码如下:

//获取InetAddress对象,可以传递ip地址或主机名
InetAddress address = InetAddress.getByName("192.168.177.130");
//获取这个IP的主机名
String name = address.getHostName();
//获取IP值
String name = address.getHostAddress();

三要素——端口号

端口号是应用程序在设备中唯一的标识,是由2个字节表示的整数,取值范围:0-65535。
其中0-1023之间的端口号用于一些知名的网络服务或应用,我们自己使用1024以上的端口号就可以了,需要注意一个端口号只能被一个应用程序使用。

三要素——协议

计算机网络中,连接和通信的规则被称为网络通信协议。最初使用的OSI参考模型(物链网传会表应)太理想化,事实上的国际标准为TCP/IP参考模型(物理链路层、网络层、传输层、应用层),这些在学习计算机网络的时候都学习过。

每一层都会有一些相应的协议:

应用层:HTTP、FTP、TelNet、DNS
传输层:TCP、UDP
网络层:IP、ICMP、ARP
物理链路层:硬件设备二进制数

在这里我们将会学习TCP、UDP协议,并且进行演示。

UDP协议:

1、用户数据报协议
2、UDP是面向无连接的通信协议。
3、速度快,有大小限制,一次最多发送64K,数据不安全,易丢失数据

TCP协议:

1、传输控制协议
2、TCP是面向连接的通信协议
3、速度慢,但没有大小限制,数据安全

UDP协议编程

UDP协议的发送数据、接收数据都需要用到DatagramSocket类。

发送数据

发送的数据是字节数组形式,因此需要将字符串转化为字节数组,然后接收方把字节数组再转化回来。

public class SendMessageDemo {public static void main(String[] args) throws IOException {/*** 创建DatagramSocket对象,可以直接指定端口,那么以后就通过这个端口往外发送数据* 若是空参构造,将会在所有可用的端口中随机指定一个进行使用*/DatagramSocket ds = new DatagramSocket();/*** 打包数据,ds的send方法需要DatagramPacket对象表示包装数据* DatagramPacket需要的参数:*      1、要发送的数据(byte数组形式)*      2、开始索引(非必要)*      3、长度*      4、要发送的地址*      5、端口号*///要发送的数据String str = "孩儿立志出乡关,学不成名誓不还";byte[] bytes = str.getBytes();//要发送的地址InetAddress address = InetAddress.getByName("127.0.0.1");//指定发送到哪个端口,发送方端口可以不确定,但是发送到哪个端口要指定int port = 10086;//打包数据DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, port);/*** 发送数据*/ds.send(packet);/*** 释放资源*/ds.close();}
}

接收数据

public class ReceiveMessageDemo {public static void main(String[] args) throws IOException {/*** 创建DatagramSocket对象,端口号必须指定成是之前发送的10086端口*/DatagramSocket ds = new DatagramSocket(10086);/*** 新建一个箱子用于接收数据,无需再指定地址和端口号,因为ds已经指定了*///空箱子byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes, bytes.length);/*** 使用receive方法取出数据,该方法是阻塞的,如果没有消息发出,这个方法就一直等待*/ds.receive(packet);/*** 解析数据*///发过来的数据是什么byte[] data = packet.getData();//发送过来的数据的长度如何int length = packet.getLength();//是从哪个地址以及端口号传输过来的数据InetAddress address = packet.getAddress();int port = packet.getPort();System.out.println(new String(data, 0, length));System.out.println("该数据是从" + address + "中的" + port + "这个端口发出的");/*** 释放资源*/ds.close();}
}

TCP协议编程

TCP传输中,发送数据(客户端)需要定义Socket对象,而接受数据(服务器端)需要定义ServerSocket对象。

由于TCP传输需要使用I/O流相关函数,所以还需要注意好中文的乱码问题,当读取数据的时候不能再使用字节流来读取了,因为一个中文对应着两个字节,按字节流读取会发生乱码,应当使用字符流读取。

发送数据

根据I/O流的相关知识,要写数据,需要用到输出流OutputStream:

public class Client {public static void main(String[] args) throws IOException {/*** 创建Socket对象,创建对象的同时会连接服务器,若连接不上则会报错*/Socket socket = new Socket("127.0.0.1", 9999);/*** 从连接通道中获取输出流,并可以写出数据*/OutputStream outputStream = socket.getOutputStream();//写出数据outputStream.write("哈哈".getBytes());/*** 释放资源*/outputStream.close();socket.close();}
}

接收数据

public class Server {public static void main(String[] args) throws IOException {/*** 创建ServerSocket对象*/ServerSocket serverSocket = new ServerSocket(9999);/*** 监听客户端的连接,底层是阻塞式*/Socket socket = serverSocket.accept();/*** 从连接通道中获取输入流来读取数据,拆分代码如下:*          InputStream inputStream = socket.getInputStream();*         //转换成字符流,因为一个汉字对应2个字节,用字节读取会乱码*         InputStreamReader inputStreamReader = new InputStreamReader(inputStream);*         //利用缓存流提高效率*         BufferedReader bufferedReader = new BufferedReader(inputStreamReader);*///写在一行:BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));int b;while((b = bufferedReader.read()) != -1){System.out.print((char) b);}/*** 释放资源,注意需要先释放socket,才能释放serverSocket(需要保证数据处理完毕)*/socket.close();serverSocket.close();}
}

三次握手和四次挥手

三次握手需要保证连接的建立,流程如下:

1、客户端向服务器端发送连接请求,等待服务器确认
2、服务器端向客户端返回一个确认信息,告诉客户端收到了请求
3、客户端向服务器再次发送确认信息(确认了他的确认),连接建立

四次挥手的作用是确认连接断开,且数据处理完毕,流程如下:

1、客户端向服务器发出取消连接请求
2、服务器向客户端返回一个响应,表示收到客户端取消请求(不是确认请求!)
3、服务器将最后的数据处理完毕
4、服务器向客户端发出确认取消信息
5、客户端再次发送确认消息,连接取消

重点是挥手的2次确认信息发出之前,必须要让服务端把消息都处理完毕。

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

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

相关文章

pytorch tensor张量的操作

import torch import torch.nn as nn import unittest# 创建一个简单的 Conv2d 层 conv_layer nn.Conv2d(in_channels3, out_channels4, kernel_size3, stride1, padding1) # input_tensor torch.randn(1, 3, 5, 5) input_tensor torch.ones(1, 3, 5, 5) # print("inpu…

【前端工程化面试题】说一下 webpack 的构建流程

类似问题是,说一下 vite 的构建流程,参考这篇文章。 初始化流程 从配置文件和shell 语句中读取合并参数,初始化需要使用的插件和执行环境所需要的参数配置文件默认是 webpack.config.js编译构建流程 解析入口模块,从入口模块开始串…

半导体物理基础-笔记

源内容参考:https://www.bilibili.com/video/BV11U4y1k7zn/?spm_id_from333.337.search-card.all.click&vd_source61654d4a6e8d7941436149dd99026962 半导体物理要解决的四个问题 载流子在哪里;如何获得足够多的载流子;载流子如何运动…

html从零开始8:css3新特性、动画、媒体查询、雪碧图、字体图标【搬代码】

css3新特性 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

linux kernel 内存踩踏之KASAN_SW_TAGS(二)

一、背景 linux kernel 内存踩踏之KASAN&#xff08;一&#xff09;_kasan版本跟hasan版本区别-CSDN博客 上一篇简单介绍了标准版本的KASAN使用方法和实现&#xff0c;这里将介绍KASAN_SW_TAGS和KASAN_HW_TAGS 的使用和背后基本原理&#xff0c;下图是三种方式的对比&#x…

萨科微半导体宋仕强介绍说

萨科微半导体宋仕强介绍说&#xff0c;电源管理芯片是指在电子设备系统中&#xff0c;负责对电能的变换、分配、检测等进行管理的芯片&#xff0c;其性能和可靠性直接影响电子设备的工作效率和使用寿命&#xff0c;是电子设备中的关键器件。萨科微slkor&#xff08;www.slkormi…

2023年中国数据智能管理峰会(DAMS上海站2023):核心内容与学习收获(附大会核心PPT下载)

随着数字经济的飞速发展&#xff0c;数据已经渗透到现代社会的每一个角落&#xff0c;成为驱动企业创新、提升治理能力、促进经济发展的关键要素。在这样的背景下&#xff0c;2023年中国数据智能管理峰会&#xff08;DAMS上海站2023&#xff09;应运而生&#xff0c;汇聚了众多…

1.逆向基础

文章目录 一、前言二、什么是逆向&#xff1f;三、软件逆向四、逆向分析技术五、文本字符六、Windows系统1.Win API2.WOW643.Windows消息机制4.虚拟内存 一、前言 原文以及后续文章可点击查看&#xff1a;逆向基础 逆向真的是一个很宏大的话题&#xff0c;而且大多数都是相当…

数据预处理 —— AI算法初识

一、预处理原因 AI算法对数据进行预处理的原因主要基于以下几个核心要点&#xff1a; 1. **数据清洗**&#xff1a; - 数据通常包含缺失值、异常值或错误记录&#xff0c;这些都会干扰模型训练和预测准确性。通过预处理可以识别并填充/删除这些不完整或有问题的数据。 2. **数…

LabVIEW智能监测系统

LabVIEW智能监测系统 设计与实现一个基于LabVIEW的智能监测系统&#xff0c;通过高效的数据采集和处理能力&#xff0c;提高监测精度和响应速度。系统通过集成传感器技术与虚拟仪器软件&#xff0c;实现对环境参数的实时监测与分析&#xff0c;进而优化监控过程&#xff0c;提…

如何实现Vuex数据持久化

Vuex是一个非常流行的状态管理工具&#xff0c;它可以帮助我们在Vue.js应用中管理和共享数据。然而&#xff0c;当应用重新加载或刷新时&#xff0c;Vuex的状态会被重置&#xff0c;这就导致了数据的丢失。那么&#xff0c;如何才能实现Vuex的数据持久化呢&#xff1f;让我们一…

C语言第二十六弹---字符串函数(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、strncat 函数的使用 2、strncmp 函数的使用 3、strstr 函数的使用和模拟实现 4、strtok 函数的使用 5、strerror 函数的使用 6、perror 函数的使用…

51单片机编程应用(C语言):串口通信

目录 通信的基本概念和种类 1.1串行通信与并行通信 ​编辑 1.2同步通信与异步通信 1.3单工&#xff0c;半双工&#xff0c;全双工 1.4通信速率 二、波特率和比特率的关系 串口通信简介&#xff1a; 1.接口标准 RS-232 2、D型9针接口定义 3.通信协议&#xff1a; …

【类与对象 -2】学习类的6个默认成员函数中的构造函数与析构函数

目录 1.类的6个默认成员函数 2.构造函数 2.1概念 2.2特性 3.析构函数 3.1析构函数的概念 3.2特性 1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;…

PWM驱动直流电机

一、知识补充; 低频时有蜂鸣器响声&#xff0c;加大PWM频率&#xff0c;超出人耳范围就可以听不到&#xff0c;20Hz~20kHz 加大频率-->减小预分频器&#xff0c;从720-->36现在频率就是20kHz这样不会影响占空比&#xff1f; 二、接线图 三、代码分析 main,c #include…

docker (四)-docker网络

默认网络 docker会自动创建三个网络&#xff0c;bridge,host,none bridge桥接网络 如果不指定&#xff0c;新创建的容器默认将连接到bridge网络。 默认情况下&#xff0c;使用bridge网络&#xff0c;宿主机可以ping通容器ip&#xff0c;容器中也能ping通宿主机。 容器之间只…

飞天使-k8s知识点21-kubernetes实操6-daemonset

文章目录 daemonsetservice endpoint pod 之间的关系service基于Service访问外部服务 daemonset DaemonSet 是 Kubernetes 中的一种资源对象&#xff0c;它确保在集群中的每个节点上都运行一个 Pod 的副本。这对于运行集群级别的守护进程&#xff08;例如日志收集器、监控代理…

链式结构实现队列

链式结构实现队列 1.队列1.1队列的概念及结构1.2队列的实现 2. 队列的各种函数实现3. 队列的全部代码实现 1.队列 1.1队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(Fi…

Python 修改window桌面背景图片

本篇为Python 修改window桌面背景图片&#xff0c;修改背景图片需要利用windows提供的api&#xff0c;以操作电脑原有功能修改背景图片。 引入类库 首先需要引入相应类库。 示例如下&#xff1a; import win32api import win32con import win32gui 修改背景图片 修改背景图…

.NET Core WebAPI中使用Log4net记录日志

一、安装NuGet包 二、添加配置 // log4net日志builder.Logging.AddLog4Net("CfgFile/log4net.config");三、配置log4net.config文件 <?xml version"1.0" encoding"utf-8"?> <log4net><!-- Define some output appenders -->…