JavaSE 基础(十三)网络编程

news2024/12/24 10:15:02

1. 概述

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

网络编程主要工作是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的。

网络编程的主要问题:

  • 如何准确定位到网络上一台或多台主机
  • 定位到主机后如何进行通信

网络网络编程要素:IP,端口号,UDP通信协议,TCP通信协议。

2. IP

IP 可唯一定位一台网络上的计算机。

本机 IP 地址为 localhost:127.0.0.1

Java 中 使用 InetAddress 类表示Internet协议(IP)地址。

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) throws UnknownHostException {
        // 查询本机地址
        InetAddress inetAddr1 = InetAddress.getByName("127.0.0.1");
        InetAddress inetAddr2 = InetAddress.getByName("localhost");
        InetAddress inetAddr3 = InetAddress.getLocalHost();
        System.out.println(inetAddr1);
        System.out.println(inetAddr2);
        System.out.println(inetAddr3);

        // 查询网站 ip 地址
        InetAddress inetAddr4 = InetAddress.getByName("www.baidu.com");
        System.out.println(inetAddr4);

        // 常用方法
        System.out.println(inetAddr4.getCanonicalHostName());   // 规范名
        System.out.println(inetAddr4.getHostAddress());  // IP
        System.out.println(inetAddr4.getHostName());    // 域名
    }
}

3. PORT

端口是设备与外界通讯交流的出口。

命令行查看端口命令

# 查看所有端口
netstat -ano
# 查看指定端口
tasklist|findstr "80"
# 查看指定端口的进程
tasklist|findstr "80"

Java InetSocketAddress

public class TestInetSocketAddress {

    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress socketAddress1 = new InetSocketAddress("localhost", 8080);
        System.out.println(socketAddress);
        System.out.println(socketAddress1);
        System.out.println(socketAddress.getAddress());
        System.out.println(socketAddress.getHostName());
        System.out.println(socketAddress.getPort());

    }
}

4. 通信协议

TCP/IP 协议

在这里插入图片描述

TCPUDP
是否连接面向连接面向非连接
传输可靠性可靠不可靠
应用场合少量数据传输大量数据
速度

三次握手

(1) 建立连接时,客户端发送syn包(seq=j)到服务器,并进入SYN_SENT状态,等待服务器确认。

(2) 服务器收到syn包,必须确认客户端的SYN(ack=j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。

(3) 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

在这里插入图片描述

四次挥手

(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。

(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。

(3) 服务器关闭客户端的连接,发送一个FIN给客户端。

(4) 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。

在这里插入图片描述

5. TCP

通信

客户端

  • 连接服务器
  • 发送消息
/**
 * TODO
 * 客户端
 * @author why
 * @since 2021/11/11 14:19
 */
public class Client {
    public static void main(String[] args) {

        InetAddress serverIp = null;
        OutputStream os = null;
        try {
            // 1. 服务器 IP,PORT
            serverIp = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            // 2. 创建 Socket 连接
            Socket socket = new Socket(serverIp, port);
            // 3. 发送消息
             os = socket.getOutputStream();
            os.write("hello!".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

服务端

  • 建立服务端口
  • 等待连接
  • 接收消息
/**
 * TODO
 * 服务端
 * @author why
 * @since 2021/11/11 14:19
 */
public class Server {
    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            // 1. 服务器地址
            serverSocket = new ServerSocket(9999);
            // 2. 等待客户端连接
            socket = serverSocket.accept();
            // 3. 读取客户端消息
            is = socket.getInputStream();
            // 套一层管道流,防止乱码
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while((len=is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            System.out.println(baos.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

文件上传

服务端

/**
 * TODO
 * 服务端
 * @author why
 * @since 2021/11/11 15:15
 */
public class Server {
    public static void main(String[] args) throws IOException {
        // 1. 创建服务
        ServerSocket serverSocket = new ServerSocket(9999);
        // 2. 监听客户端连接
        Socket socket = serverSocket.accept();
        // 3. 获取输入流
        InputStream is = socket.getInputStream();
        // 4. 文件输出
        FileOutputStream fos = new FileOutputStream(new File("./resources/receive/test.txt"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len=is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }

        // 5. 通知客户端接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("receive over !".getBytes());

        // 6. 关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

客户端

/**
 * TODO
 * 客户端
 * @author why
 * @since 2021/11/11 15:09
 */
public class Client {
    public static void main(String[] args) throws Exception {
        // 1. 创建 Socket 连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
        // 2. 创建输出流
        OutputStream os = socket.getOutputStream();
        // 3. 读取文件
        FileInputStream fis = new FileInputStream(new File("./resources/send/test.txt"));
        // 4. 写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len=fis.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
        // 5. 传输完毕
        socket.shutdownOutput();
        // 6. 确认服务器接收完毕
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] infoBuffer = new byte[1024];
        int infoLen;
        while ((infoLen=is.read(infoBuffer)) != -1) {
            baos.write(infoBuffer, 0, infoLen);
        }
        System.out.println(baos.toString());
        // 7. 关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}

6. UDP

发送端

/**
 * TODO
 * UDP 客户端,不需要建立连接
 * @author why
 * @since 2021/11/11 16:04
 */
public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 建立 Socket
        DatagramSocket socket = new DatagramSocket();
        // 2. 建立一个包
        String msg = "Hello!";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
        // 3. 发送包
        socket.send(packet);
        // 4. 关闭流
        socket.close();
    }
}

接受端

/**
 * TODO
 * UDP 服务端
 * @author why
 * @since 2021/11/11 16:10
 */
public class Server {
    public static void main(String[] args) throws IOException {
        // 1. 开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        // 2. 接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet);
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(), 0, packet.getData().length));
        // 2. 关闭连接
        socket.close();
    }
}

7. URL

统一资源定位符:定位互联网资源。

DNS 域名解析:将 ip 映射成为域名,或将域名解析为 ip。

构成 :协议://ip:端口/项目名/资源

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

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

相关文章

基于ModebusRTU通信采集温度湿度项目案例

目录 一、模拟温湿度模拟 【1.1】温湿度仪表参数 【1.1】使用电脑模拟传感器 【1.2】使用Codesys软件模拟传感器 二、自定义控件UI设计 【2.1】自定义控件温度湿度柱状设计 ​编辑 【2.1.1】设置温度湿度柱状实际显示【属性】 【2.1.2】设置温度湿度柱状的背景颜色【属…

工具篇 | Gradle入门与使用指南 - 附Github仓库地址

介绍 1.1 什么是Gradle? Gradle是一个开源构建自动化工具,专为大型项目设计。它基于DSL(领域特定语言)编写,该语言是用Groovy编写的,使得构建脚本更加简洁和强大。Gradle不仅可以构建Java应用程序&#x…

用AI解决量子学问题

3 人工智能用于量子力学 在这一部分中,我们提供了有关如何设计高级深度学习方法以有效学习神经波函数的技术评述。在第3.1节中,我们概述了一般情况下定义和解决量子多体问题的方法。在第3.2节中,我们介绍了学习量子自旋系统基态的方法。在第…

Python3操作SQLite3创建表主键自增长|CRUD基本操作

Python3操作MySQL8.XX创建表|CRUD基本操作 Python3操作SQLite3创建表主键自增长|CRUD基本操作 一: SQLite3创建表时主键自增长 1: sqlite支持建立自增主键 create table t_user (id integer primary key autoincrement,age int(2), name varchar(10),address varchar(100) )…

YOLOv5、YOLOv8改进:ConvNeXt(backbone改为ConvNextBlock)

目录 1.介绍 2. YOLOv5修改backbone为ConvNeXt 2.1修改common.py 2.2 修改yolo.py 2.3修改yolov5.yaml配置 1.介绍 论文地址:https://arxiv.org/abs/2201.03545官方源代码地址:https://github.com/facebookresearch/ConvNeXt.git 自从ViT(Vision T…

Linux 权限相关例题练习

目录 一、前期准备工作: 1)新建redhat用户 2)新建testdir目录及其file1 二、例题详解 1、当用户redhat对/testdir目录无写权限时,该目录下的只读文件file1是否可修改和删除? 2、复制/etc/fstab文件到/var/tmp下&…

C++11之新的类功能

这里写目录标题 新的类功能默认成员函数类成员变量初始化强制生成默认函数的关键字default禁止生成默认函数的关键字deletefinal与override关键字override 新的类功能 默认成员函数 原来C类中,有6个默认成员函数: 构造函数析构函数拷贝构造函数拷贝赋…

Spring学习笔记13 Spring对事务的支持

Spring学习笔记12 面向切面编程AOP-CSDN博客 什么是事务:在一个业务流程当中,通常需要多条DML(insert delete update)语句共同联合才能完成,这多条DML语句必须同时成功,或者同时失败,这样才能保证数据的安全. 多条DML要么同时成功,要么同时失败,叫做事务(Transaction) 事务四…

安防视频平台EasyCVR视频调阅全屏播放显示异常是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

Apache DolphinScheduler在中国信通院“2023 OSCAR开源尖峰案例”评选中荣获「尖峰开源项目奖」!

在近日由中国信息通信研究院(以下简称“中国信通院”)和中国通信标准化协会联合主办的“2023 OSCAR 开源产业大会”上,主办方公布了 2023 年“OSCAR 开源尖峰案例”评选结果,包括“开源人物”“开源项目”“开源社区”“开源企业”…

python+vue实验室课程预约管理系统

实验室课程管理系统运用计算机完成数据收集、查询、修改和删除以及统计等工作,提高了管理者工作效率,避免了因信息量巨大,造成的人为错误.通过前面的功能分析可以将实验室课程管理系统的功能分为管理员、学生和教师三个部分&#…

Linux高性能服务器编程 学习笔记 第八章 高性能服务器程序框架

TCP/IP协议在设计和实现上没有客户端和服务器的概念,在通信过程中所有机器都是对等的。但由于资源(视频、新闻、软件等)被数据提供者所垄断,所以几乎所有网络应用程序都采用了下图所示的C/S(客户端/服务器)…

LeetCode_BFS_中等_1926.迷宫中离入口最近的出口

目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 ‘.’ 表示)和墙(用 ‘’ 表示)。同时给你迷宫的入口 …

电脑提示vcruntime140.dll缺失重新安装的修复方法

电脑出现 vcruntime140.dll 丢失的情况,通常是由于系统缺失了 Microsoft Visual C Redistributable 的运行库文件。这个文件是许多应用程序在运行时所需的依赖库,如果丢失了该文件,可能会导致某些软件无法正常运行。 下面是关于 vcruntime140…

免费录音软件推荐,告别杂音,音质更清晰!

“求推荐一款免费的录音软件!最近下载了好多的录音软件,不是音质太差,就是需要收费解锁新的功能,根本不好用,有没有人知道一款免费优秀的录音软件呀,告诉我一下。” 录音已成为现代人们学习和工作中的一项…

DataExcel控件读取和保存excel xlsx 格式文件

需要引用NPOI库 https://github.com/dotnetcore/NPOI 调用Read 函数将excel读取到dataexcel控件 调用Save 函数将dataexcel控件文件保存为excel文件 using NPOI.HSSF.UserModel; using NPOI.HSSF.Util; using NPOI.SS.UserModel; using NPOI.SS.Util; using System; using …

pytho实例--pandas读取表格内容

前言:由于运维反馈帮忙计算云主机的费用,特编写此脚本进行运算 如图,有如下excel数据 计算过程中需用到数据库中的数据,故封装了一个读取数据库的类 import MySQLdb from sshtunnel import SSHTunnelForwarderclass SSHMySQL(ob…

Java BigDecimal 详解

目录 一、BigDecimal 1、简介 2、构造器描述 3、方法描述 4、使用 一、BigDecimal float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它…

25841-2017 1000kV电力系统继电保护技术导则

声明 本文是学习GB-T 25841-2017 1000kV电力系统继电保护技术导则. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了交流1000 kV 系统及1000 kV 变电站相关电压等级具有特别要求的继电保护装置 的基本准则。 本标准适用于1000 k…

大厂秋招真题【BFS+DP】华为20230921秋招T3-PCB印刷电路板布线【欧弟算法】全网最全大厂秋招题解

题目描述与示例 题目描述 在PCB印刷电路板设计中,器件之间的连线,要避免线路的阻抗值增大,而且器件之间还有别的器任和别的干扰源,在布线时我们希望受到的干扰尽量小。 现将电路板简化成一个M N的矩阵,每个位置&am…