Java网络编程笔记(一)(下)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: Java网络编程笔记(一)(下)

1.UDP


用户数据报协议(User Datagram Protocol)。


数据报(Datagram):网络传输的基本单位


UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。


由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。


但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时,不建议使用UDP协议。


特点:数据被限制在64kb以内,超出这个范围就不能发送了。


2.TCP


传输控制协议(Transmission Control Protocol)。

TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。

在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。


三次握手


TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。

9988e7f4a9f44ff8b400d49499eeb96f.png

第一次握手: SYN=1 seq=x.SYN=1,ACK=0.表示为请求连接报文,(这里ACK=0省略)

seq表示主机A向主机B协商从序号为x发送数据报


这里需要注意的是,A向B的连接未建立无法传送数据,所以该请求报文消耗序号最小,消耗1个序号


第二次握手 SYN=1,ACK=1,seq=y,ack=x+1。


SYN=1,ACK=1表示同意建立A向B的连接,seq=y表示从序号为y的报文段开始发送,


ack=x+1表示已收到序号x的报文段,期望收到x+1序号的数据,即已收到序号x。第一次的请求报文消耗了1个序号


ack=x+1确认了第一次报文的收到,并请求B向A的连接


第三次握手 SYN=1,ACK=1,seq=x+1,ack=y+1 。


seq=x+1表示自己从序号x+1开始发送,期望收到主机B序号y+1的数据


第三次报文确认了前两次请求报文的收到。


四次挥手


693670c038bb4f4dbd51d1cf659648e6.png


第一次挥手 FIN=1表示请求关闭A向B的连接 seq=u 已发送u-1序号的数据报


第二次挥手 ACK=1,同意关闭A向B的连接。seq=v,B向A发送的数据报序号为v。ack=u+1已收到u序号数据报


此时A向B方向的连接已经关闭,中间保持一段时间单向B向A连接


第三次挥手 FIN=1 seq=w


FIN=1,请求关闭B向A连接。seq=w,从序号为w开始向A发送。


这里ack=u+1是因为前两次已经关闭了客户向服务器这个方向的链接。


第四次挥手 ACK=1,seq=u+1,ack=w+1。


ACK=1,同意关闭B向A连接。seq=u+1,因为A向B的连接已关闭,故这里是u+1。ack=w+1,已收到序号w的报文段,期望收到w+1序号的报文段。


为什么挥手需要四次?

关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次


通俗理解:


  • 三次握手 A:我要过来了!B:我知道你要过来了!A:我现在过来!
  • 四次挥手 A:我们分手吧!B:真的分手吗?B:真的真的要分手吗?A:是的!

由此,可以可靠地进行连接和断开。


四、IP协议


(一)IP协议的的概念


7eb805fc8ba543658cfd5b7bd5b2d908.png


每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了。


(二)IP地址的分类


IP地址根据版本可以分类为:IPv4和IPv6

75102f4cbf404203a379e1a82acc1b76.png

1e22625b13434f0aae165dcf5d301a78.png

IPv4又可以分为五类:

7b61995bbb484014bda84ac7734f3764.png

A类:在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码;A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万(256的三次方-2)台。


B类:在IP地址的四段号码中,前两段号码为网络号码。B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多(256的二次方-2)台


C类:在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码;此类地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254(256-2)台计算机


D类:此类IP地址在历史上被叫做多播地址(multicast address),即组播地址;在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点;多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255


E类: 此类地址也不分网络地址和主机地址,它的第1个字节的前五位固定为“11110”,为将来使用保留,地址范围从240.0.0.1到255.255.255.254-


(三)Java InetAddress类


说到IP地址,就要引入一个类:InetAddress

此类表示互联网协议 (IP) 地址。


特别说明: InetAddress类无构造方法


常用方法摘要


方法名 实现功能
byte[] getAddress() 返回此 InetAddress 对象的原始 IP 地址。
static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
String getHostName() 获取此 IP 地址的主机名。
static InetAddress getLocalHost() 返回本地主机。


127.0.0.1:本机地址,主要用于测试。别名:Localhost


测试样例一

import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestIP {
    public static void main(String[] args) throws UnknownHostException {
        //InetAddress类表示IP地址
        //获取本机IP
        InetAddress ip = InetAddress.getLocalHost();
        System.out.println(ip);  //Cdy-Pc/192.168.43.99
        //获得主机名
        System.out.println(ip.getHostName());  //Cdy-Pc
        //获得ip地址
        System.out.println(ip.getHostAddress());//192.168.43.99
        //查找主机名为xxx的IP地址
        System.out.println(InetAddress.getByName("localhost"));
        //localhost/127.0.0.1
        //其中127.0.0.1为默认本机的主机地址
    }
}

测试样例二

import java.net.InetAddress;
import java.net.UnknownHostException;
public class TestIP2 {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress inetAddress = InetAddress.getByName("www.baidu.com");
        // 获取此 IP 地址的主机名。
        System.out.println(inetAddress.getHostName());
        //返回 IP 地址字符串(以文本表现形式)。
        System.out.println(inetAddress.getHostAddress());
    }
}

67d92df053eb47ca85a16516a8fa346e.png


五、端口


IP地址用来标识一台计算机,但是一台计算机上可能提供多种网络应用程序,如何来区分这些不同的程序呢?这就要用到端口。端口号是用来区分一台机器上不同的应用程序的。

我们使用IP地址加端口号,就可以保证数据准确无误地发送到对方计算机的指定软件上了。

端口是虚拟的概念,是一个逻辑端口。

当我们使用网络软件一打开,那么操作系统就会为网络软件分配一个随机的端口号,或者打开的时候向系统要指定的端口号。

通过端口,可以在一个主机上运行多个网络应用程序。端口的表示是一个16位的二进制整数,2个字节,对应十进制的0~65535。

端口号在计算机内部是占2个字节。一台机器上最多有65536个端口号。一个应用程序可以占用多个端口号。端口号如果被一个应用程序占用了,那么其他的应用程序就无法再使用这个端口号了。

记住一点,我们编写的程序要占用端口号的话占用1024以上的端口号,1024以下的端口号不要去占用,因为系统有可能会随时征用。端口号本身又分为TCP端口和UDP端口,TCP的8888端口和UDP的8888端口是完全不同的两个端口。TCP端口和UDP端口都有65536个。


(一)端口分类


公有端口:0~1023

1.HTTP:80

2.HTTPS:443

3.FTP:21

4.Telnet:23

.程序注册端口(分配给用户或者程序):1024~49151

Tomcat:8080

MySQL:3306

Oracle:1521

动态、私有端口:49152~65535


(二)DOS命令查看端口


  • 查看所有端口:netstat -ano
  • 查看指定端口:netstat -ano|findstr "端口号"
  • 查看指定端口的进程:tasklist|findstr "端口号"


(三)InetSocketAddress类


说到端口,则要引入一个类:InetSocketAddress

此类实现 IP 套接字(Socket)地址(IP 地址 + 端口号)。


1.构造方法摘要


InetSocketAddress(InetAddress addr, int port)

根据 IP 地址和端口号创建套接字地址。

InetSocketAddress(int port)

创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。

InetSocketAddress(String hostname, int port)

根据主机名和端口号创建套接字地址。


2.常用方法摘要


InetAddress getAddress()

获取 InetAddress。

String getHostName()

获取 hostname。

int getPort()

获取端口号。


演示案例

import java.net.InetSocketAddress;
public class Testport {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress("8.8.8.8", 8082);
        System.out.println(inetSocketAddress);
        System.out.println(inetSocketAddress.getAddress());
        System.out.println(inetSocketAddress.getHostName());
        System.out.println(inetSocketAddress.getPort());
    }
}

0b97957725e64a24a324bd6e5e4b9963.png



相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
6天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
|
6天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑】设计模式——原型模式
对比原型模式和传统方式的实现思路、代码方案、优缺点,阐述原型模式的使用场景,以及深拷贝、浅拷贝等相关概念,并扩展原型模式在Spring源码中的应用。
【Java笔记+踩坑】设计模式——原型模式
|
7天前
|
Java 开发者 数据格式
【Java笔记+踩坑】SpringBoot基础4——原理篇
bean的8种加载方式,自动配置原理、自定义starter开发、SpringBoot程序启动流程解析
【Java笔记+踩坑】SpringBoot基础4——原理篇
消息中间件 缓存 监控
28 0
|
7天前
|
运维 Java 关系型数据库
【Java笔记+踩坑】SpringBoot基础2——运维实用
SpringBoot程序的打包与运行、临时配置、多环境配置、日志
【Java笔记+踩坑】SpringBoot基础2——运维实用
|
7天前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
7天前
|
SQL Java 数据库连接
【Java笔记+踩坑】MyBatisPlus基础
MyBatisPlus简介、标准数据层开发CRUD、业务层继承IService、ServiceImpl、条件查询、LambdaQueryWrapper、id生成策略、逻辑删除、乐观锁@Version、代码生成器、ActiveRecord
【Java笔记+踩坑】MyBatisPlus基础
|
7天前
|
前端开发 Java 数据库连接
【Java笔记+踩坑】SpringBoot——基础
springboot三种配置文件及其优先级、多环境配置、springboot整合junit,mybatis、ssmp综合图书案例
【Java笔记+踩坑】SpringBoot——基础
|
7天前
|
Java 数据库连接 Maven
【Java笔记+踩坑】Maven高级
分模块开发、依赖传递与冲突问题、 可选依赖和排除依赖、聚合和继承、属性、多环境配置与应用、私服安装和使用
【Java笔记+踩坑】Maven高级
|
7天前
|
前端开发 Java 数据库连接
【Java笔记+踩坑】SSM整合
统一结果封装、统一异常处理、整合图书案例、拦截器
【Java笔记+踩坑】SSM整合