Java网络编程

简介: Java网络编程

我是南城余!阿里云开发者平台专家博士证书获得者!

欢迎关注我的博客!一同成长!

一名从事运维开发的worker,记录分享学习。

专注于AI,运维开发,windows Linux 系统领域的分享!


软件架构

  • C/S架构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、美团app、360安全卫士等软件。

  • B/S架构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有IE、谷歌、火狐等。


两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机的通信的程序。

网络传输

实现网络传输的三个要素

》使用IP地址(准确地定位网络上一台或多台主机)

》使用端口号(定位主机上的特定应用)

》规范网络通信协议(可靠、高效地进行数据传输)

IP地址

作用:用来给网络中地一台计算机设备做唯一地编号

IP地址分类

》IP地址分类方式1

IPv4(占用4个字节) IPv6(占用16个字节)

》IP地址分类方式2

公网地址(万维网使用)和私有地址(局域网使用,以192.168开头)

本地回路地址

127.0.0.1

端口号

》可以唯一识别主机中的进程(应用程序)

》不同进程分配不同的端口号

》范围0~65535

网络通信协议

  • OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广
  • TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。

Java:InetAddress类

InetAddress类主要表示IP地址

InetAddress 类没有提供公共的构造器,而是提供 了 如下几个 静态方法来获取InetAddress 实例

  • public static InetAddress getLocalHost()
  • public static InetAddress getByName(String host)
  • public static InetAddress getByAddress(byte[] addr)

InetAddress 提供了如下几个常用的方法

  • public String getHostAddress() :返回 IP 地址字符串(以文本表现形式)
  • public String getHostName() :获取此 IP 地址的主机名
  • public boolean isReachable(int timeout):测试是否可以达到该地址
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.junit.Test;
public class TestInetAddress {
    @Test
    public void test01() throws UnknownHostException{
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);
    }
    @Test
    public void test02()throws UnknownHostException{
        InetAddress atguigu = InetAddress.getByName("www.atguigu.com");
        System.out.println(atguigu);
    }
    @Test
    public void test03()throws UnknownHostException{
//    byte[] addr = {112,54,108,98};
        byte[] addr = {(byte)192,(byte)168,24,56};
        InetAddress atguigu = InetAddress.getByAddress(addr);
        System.out.println(atguigu);
    }
}

TCP协议与UDP协议

TCP协议:

可靠的连接(发送数据前,需要三次握手,结束时,四次挥手),进行大数据量的传输,效率低

  • TCP协议进行通信的两个应用进程:客户端、服务端。
  • 使用TCP协议前,须先建立TCP连接,形成基于字节流的传输数据通道
  • 传输前,采用“三次握手”方式,点对点通信,是可靠的
  • TCP协议使用重发机制,当一个通信实体发送一个消息给另一个通信实体后,需要收到另一个通信实体确认信息,如果没有收到另一个通信实体确认信息,则会再次重复刚才发送的消息。
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低

UDP协议:

不可靠连接(发送前,不需要确认对方是否存在),使用数据报传输(限制在64kb以内),效率高

  • UDP协议进行通信的两个应用进程:发送端、接收端。
  • 将数据、源、目的封装成数据包(传输的基本单位),不需要建立连接
  • 发送不管对方是否准备好,接收方收到也不确认,不能保证数据的完整性,故是不可靠的
  • 每个数据报的大小限制在64K内
  • 发送数据结束时无需释放资源,开销小,通信效率高
  • 适用场景:音频、视频和普通数据的传输。例如视频会议

TCP生活案例:打电话

UDP生活案例:发送短信、发电报

三次握手

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

  • 第一次握手,客户端向服务器端发起TCP连接的请求
  • 第二次握手,服务器端发送针对客户端TCP连接请求的确认
  • 第三次握手,客户端发送确认的确认

1、客户端会随机一个初始序列号seq=x,设置SYN=1 ,表示这是SYN握手报文。然后就可以把这个 SYN 报文发送给服务端了,表示向服务端发起连接,之后客户端处于同步已发送状态。

2、服务端收到客户端的 SYN 报文后,也随机一个初始序列号(seq=y),设置ack=x+1,表示收到了客户端的x之前的数据,希望客户端下次发送的数据从x+1开始。设置 SYN=1 和 ACK=1。表示这是一个SYN握手和ACK确认应答报文。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于同步已接收状态。

3、客户端收到服务端报文后,还要向服务端回应最后一个应答报文,将ACK置为 1 ,表示这是一个应答报文ack=y+1 ,表示收到了服务器的y之前的数据,希望服务器下次发送的数据从y+1开始。最后把报文发送给服务端,这次报文可以携带数据,之后客户端处于 连接已建立 状态。服务器收到客户端的应答报文后,也进入连接已建立状态。

完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏览网页等。

四次挥手

TCP协议中,在发送数据结束后,释放连接时需要经过四次挥手。

  • 第一次挥手:客户端向服务器端提出结束连接,让服务器做最后的准备工作。此时,客户端处于半关闭状态,即表示不再向服务器发送数据了,但是还可以接受数据。
  • 第二次挥手:服务器接收到客户端释放连接的请求后,会将最后的数据发给客户端。并告知上层的应用进程不再接收数据。
  • 第三次挥手:服务器发送完数据后,会给客户端发送一个释放连接的报文。那么客户端接收后就知道可以正式释放连接了。
  • 第四次挥手:客户端接收到服务器最后的释放连接报文后,要回复一个彻底断开的报文。这样服务器收到后才会彻底释放连接。这里客户端,发送完最后的报文后,会等待2MSL,因为有可能服务器没有收到最后的报文,那么服务器迟迟没收到,就会再次给客户端发送释放连接的报文,此时客户端在等待时间范围内接收到,会重新发送最后的报文,并重新计时。如果等待2MSL后,没有收到,那么彻底断开。

1、客户端打算断开连接,向服务器发送FIN报文(FIN标记位被设置为1,1表示为FIN,0表示不是),FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态。也就是客户端发出连接释放报文段(FIN报文),指定序列号seq = u,主动关闭TCP连接,等待服务器的确认。

2、服务器收到连接释放报文段(FIN报文)后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1。接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态(下面会说什么是半关闭状态),客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。

3、服务器也打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。

4、客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。

之后客户端进入TIME_WAIT(时间等待)状态,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态,到此服务器的连接已经完成关闭。客户端处于TIME_WAIT状态时,此时的TCP还未释放掉,需要等待2MSL后,客户端才进入CLOSE状态。

JavaSocket类

  • 网络上具有唯一标识的IP地址和端口号组合在一起构成唯一能识别的标识符套接字(Socket)。
  • 利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准。网络通信其实就是Socket间的通信。
  • 通信的两端都要有Socket,是两台机器间通信的端点。
  • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
  • 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端。
  • Socket分类:
  • 流套接字(stream socket):使用TCP提供可依赖的字节流服务
  • ServerSocket:此类实现TCP服务器套接字。服务器套接字等待请求通过网络传入。
  • Socket:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
  • 数据报套接字(datagram socket):使用UDP提供“尽力而为”的数据报服务
  • DatagramSocket:此类表示用来发送和接收UDP数据报包的套接字。
//客户端发送内容给服务端,服务端将内容打印到控制台上。
//客户端 发出方:outputimport java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
    public static void main(String[] args) throws Exception {
        // 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1", 8888);
        // 2、获取输出流,用来发送数据给服务器
        OutputStream out = socket.getOutputStream();
        // 发送数据
        out.write("lalala".getBytes());
        //会在流末尾写入一个“流的末尾”标记,对方才能读到-1,否则对方的读取方法会一致阻塞
        socket.shutdownOutput();
        //3、获取输入流,用来接收服务器发送给该客户端的数据
        InputStream input = socket.getInputStream();
        // 接收数据
        byte[] data = new byte[1024];
        StringBuilder s = new StringBuilder();
        int len;
        while ((len = input.read(data)) != -1) {
            s.append(new String(data, 0, len));
        }
        System.out.println("服务器返回的消息是:" + s);
        //4、关闭socket,不再与服务器通信,即断开与服务器的连接
        //socket关闭,意味着InputStream和OutputStream也关闭了
        socket.close();
    }
}
//服务器:接受方 input
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
    public static void main(String[] args)throws Exception {
        //1、准备一个ServerSocket对象,并绑定8888端口
        ServerSocket server =  new ServerSocket(8888);
        System.out.println("等待连接....");
        //2、在8888端口监听客户端的连接,该方法是个阻塞的方法,如果没有客户端连接,将一直等待
        Socket socket = server.accept();
        InetAddress inetAddress = socket.getInetAddress();
        System.out.println(inetAddress.getHostAddress() + "客户端连接成功!!");
        //3、获取输入流,用来接收该客户端发送给服务器的数据
        InputStream input = socket.getInputStream();
        //接收数据
        byte[] data = new byte[1024];
        StringBuilder s = new StringBuilder();
        int len;
        while ((len = input.read(data)) != -1) {
            s.append(new String(data, 0, len));
        }
        System.out.println(inetAddress.getHostAddress() + "客户端发送的消息是:" + s);
        //4、获取输出流,用来发送数据给该客户端
        OutputStream out = socket.getOutputStream();
        //发送数据
        out.write("欢迎登录".getBytes());
        out.flush();
        //5、关闭socket,不再与该客户端通信
        //socket关闭,意味着InputStream和OutputStream也关闭了
        socket.close();
        //6、如果不再接收任何客户端通信,可以关闭ServerSocket
        server.close();
    }
}

URL

作用:一个具体的url对应着互联网上某一资源的地址

URL格式

网络编程 · 语雀

应用层协议 ip地址+端口号——》对应的域名 资源地址 参数列表

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
6天前
|
网络协议 算法 Java
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
【Java网络编程】网络编程概述、UDP通信(DatagramPacket 与 DatagramSocket)
19 3
|
1天前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
3天前
|
前端开发 JavaScript Java
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)五(前端页面
|
6天前
|
Java 开发者 Spring
Java一分钟之-Java网络编程基础:Socket通信
【5月更文挑战第13天】本文介绍了Java Socket编程基础知识,包括使用`ServerSocket`和`Socket`类建立连接,通过`OutputStream`和`InputStream`进行数据传输。常见问题涉及忘记关闭Socket导致的资源泄漏、网络异常处理及并发同步。理解Socket通信原理并掌握异常处理、资源管理和并发控制,能帮助开发者构建更稳定的网络应用。
31 1
|
6天前
|
网络协议 Dubbo Java
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器
11 0
|
6天前
|
安全 Java 网络安全
深入理解Java异常处理网络安全与信息安全:保护数据的关键策略
【4月更文挑战第29天】本文将深入探讨Java中的异常处理机制,包括异常的概念、分类、捕获和处理等方面。通过详细的解析和实例演示,帮助读者更好地理解Java异常处理的原理和应用。 【4月更文挑战第29天】在数字化时代,数据成为最宝贵的资产之一。随着网络攻击的日益猖獗,了解并实施有效的网络安全和信息保护措施变得至关重要。本文将深入探讨网络安全漏洞的概念、加密技术的重要性以及提升个人和企业的安全意识的必要性。我们将分析当前的安全挑战,并提供一系列实用的防护策略,旨在帮助读者构建一个更加安全的数字环境。
|
6天前
|
网络协议 Java 网络架构
Java基础教程(18)-Java中的网络编程
【4月更文挑战第18天】Java网络编程简化了底层协议处理,利用Java标准库接口进行TCP/IP通信。TCP协议提供可靠传输,常用于HTTP、SMTP等协议;UDP协议则更高效但不保证可靠性。在TCP编程中,ServerSocket用于监听客户端连接,Socket实现双进程间通信。UDP编程中,DatagramSocket处理无连接的数据报文。HTTP编程可以通过HttpURLConnection发送请求并接收响应。
|
6天前
|
监控 网络协议 Java
《Java 简易速速上手小册》第7章:Java 网络编程(2024 最新版)
《Java 简易速速上手小册》第7章:Java 网络编程(2024 最新版)
24 0
《Java 简易速速上手小册》第7章:Java 网络编程(2024 最新版)
|
6天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
JSON 前端开发 安全
Java网络编程IO模型 --- BIO、NIO、AIO详解
Java网络编程IO模型 --- BIO、NIO、AIO详解
306 0
Java网络编程IO模型 --- BIO、NIO、AIO详解