14、Java网络编程

news2024/10/7 16:21:22

一、 网络编程概述

Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。

计算机网络:把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息、共享硬件、软件、数据信息等资源。

1、网络编程的目的

直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯。

2、网络编程中有两个主要的问题

①如何准确地定位网络上一台或多台主机;定位主机上的特定的应用。

②找到主机后如何可靠高效地进行数据传输。

3、网络编程的两个要素:

①对应问题一:IP和端口号。

②对应问题二:网络通信协议(TCP/IP协议)(应用层、传输层、网络层、数据链路层、物理层)。

二、InetAddress类的使用

1、通信要素一:IP和端口号

1.1、IP的理解

①IP地址:唯一的标识 Internet 上的计算机(通信实体)

②IP地址分类方式1:IPV4 和 IPV6

③IP地址分类方式2:公网地址(万维网使用)和私地址(局域网使用)。

④在Java中使用InetAddress类表示IP

⑤域名:www.baidu.com、www.mi.com、www.sina.com;域名解析:域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS) 负责将域名转化成IP地址,这样才能和主机建立连接。

⑥本地地址:127.0.0.1 对应着:localhost

1.2、InetAddress类:此类的一个对象代表着一个IP

①实例化

getByName(String host)\getLocalHost()

②常用方法

getHostNmae()\getHostAddress()

public static void main(String[] args) {
        try {
            InetAddress inet1 = InetAddress.getByName("192.168.1.117");
            System.out.println(inet1);

            InetAddress inet2 = InetAddress.getByName("www.baidu.com");
            System.out.println(inet2);

            InetAddress inet3 = InetAddress.getByName("127.0.0.1");
            System.out.println(inet3);

            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost);

            //getHostName()
            System.out.println(inet2.getHostName());
            //getHostAddress()
            System.out.println(inet2.getHostAddress());


        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

1.3、端口号:标识正在计算机上运行的进程(程序)

①要求:不同的进程不同的端口号

②范围:被规定为一个 16 位的整数 0~65535。

③端口号与IP地址的组合得出一个网络套接字:Socket

2、通信要素二:网络通信协议

2.1、分型模型

2.2、TCP和UDP的区别

①TCP协议:

🔷使用TCP协议前,须先建立TCP连接,形成传输数据通道。

🔷传输前,采用“三次握手”方式,点对点通信,是可靠的。

🔷TCP协议进行通信的两个应用进程:客户端、服务端。

🔷在连接中可进行大数据量的传输。

🔷传输完毕,需释放已建立的连接,效率低。

②UDP协议:

🔷将数据、源、目的封装成数据包,不需要建立连接。

🔷每个数据报的大小限制在64K内。

🔷发送不管对方是否准备好,接收方收到也不确认,故是不可靠的。

🔷可以广播发送。

🔷发送数据结束时无需释放资源,开销小,速度快。

三、TCP网络编程

Java语言的基于套接字编程分为服务端编程和客户端编程,其通信模型如图所示:

1、客户端Socket的工作过程包含以下四个基本的步骤:

①创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。

②打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输

③按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。

④关闭 Socket:断开客户端到服务器的连接,释放线路

2、服务器程序的工作过程包含以下四个基本的步骤:

①调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。

②调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。

③调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。

④关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

3、代码实现

①客户端发送内容给服务端,服务端将内容打印到控制台上。

/*
    TCP网络编程
    1.客户端发送内容给服务端,服务端将内容打印到控制台上。
     */
    //客户端
    @Test
    public void client(){
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.创建Socket对象,指明要访问的服务器的ip和端口号
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet,8899);
            //2.获取输出流
            os = socket.getOutputStream();
            //3.用输出流,输出数据操作
            os.write("你好,我是客户端".getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //4.关闭流资源
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }



    }
    //服务端
    @Test
    public void sever(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.创建服务器端的ServerSocket,指明自身的端口号
            ss = new ServerSocket(8899);
            //2.ServerSocket的对象调用accept()方法,创建socket对象
            socket = ss.accept();
            //3.socket对象获取输入流
            is = socket.getInputStream();

            //不建议这样写,可能会出现乱码
//        byte[] buffer = new byte[20];
//        int len;
//        while((len = is.read(buffer)) != -1){
//            String str = new String(buffer,0,len);
//            System.out.println(str);
//        }
            //4.使用输入流操作数据
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[5];
            int len;
            while((len = is.read(buffer)) != -1){
                baos.write(buffer,0,len);
            }
            System.out.println(baos.toString());
            System.out.println(socket.getInetAddress().getHostAddress());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //5.关闭流资源
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(ss != null){
                try {
                    ss.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

②客户端发送文件给服务端,服务端将文件保存在本地。

    /*
    TCP网络编程
    例题2:客户端发送文件给服务端,服务端将文件保存在本地。
     */
    //客户端
    @Test
    public void client() throws IOException {
        //创建Socket的对象,指明访问的ip和端口号
        InetAddress localhost = InetAddress.getByName("localhost");
        Socket socket = new Socket(localhost, 7788);

        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream("1730092804.jpeg");
        //4.操作数据
        byte[] buffer = new byte[20];
        int len;
        while((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }
        //关闭流资源
        os.close();
        fis.close();
        socket.close();

    }

    //服务端
    @Test
    public void server() throws IOException {
        //1.
        ServerSocket ss = new ServerSocket(7788);
        //2.
        Socket socket = ss.accept();

        //3.
        InputStream is = socket.getInputStream();

        //4.
        FileOutputStream fos = new FileOutputStream("新1730092804.jpeg");

        //5.
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        //6
        fos.close();
        is.close();
        ss.close();
    }

③从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。

    /*
    3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。
     */
    //客户端
    @Test
    public void client() throws IOException {
        //创建Socket的对象,指明访问的ip和端口号
        InetAddress localhost = InetAddress.getByName("localhost");
        Socket socket = new Socket(localhost, 7788);

        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        //3.获取输入流
        FileInputStream fis = new FileInputStream("1730092804.jpeg");
        //4.操作数据
        byte[] buffer = new byte[20];
        int len;
        while((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }
        //表示已经发完数据
        socket.shutdownOutput();
        //5.客户端接受服务端的信息
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buufer = new byte[20];
        int len1;
        while((len1 = is.read(buffer)) != -1){
            baos.write(buffer,0,len1);
        }
        System.out.println(baos.toString());

        //6.关闭流资源
        os.close();
        fis.close();
        socket.close();
        baos.close();

    }

    //服务端
    @Test
    public void server() throws IOException {
        //1.
        ServerSocket ss = new ServerSocket(7788);
        //2.
        Socket socket = ss.accept();

        //3.
        InputStream is = socket.getInputStream();

        //4.
        FileOutputStream fos = new FileOutputStream("新新新1730092804.jpeg");

        //5.
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }
        System.out.println("图片传输完成");

        //6.服务器端给予客户端反馈
        OutputStream os = socket.getOutputStream();
        os.write("图片已收到!谢谢。".getBytes());

        //6
        fos.close();
        is.close();
        ss.close();
        os.close();
    }

四、UDP网络编程

DatagramSocketDatagramPacket 实现了基于 UDP 协议网络程序。

UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。

DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。

UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。如同发快递包裹一样。

DatagramSocket 类的常用方法:

DatagramPacket类的常用方法 :

UDP网络通信流程:

1、DatagramSocket与DatagramPacket

2、建立发送端,接收端

3、建立数据包

4、调用Socket的发送、接收方法

5、关闭Socket

代码实现:

    //发送端
    @Test
    public void sender() throws IOException {
        DatagramSocket socket = new DatagramSocket();

        String str = "这是通过UDP协议发送的数据";
        byte[] data = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();

        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);

        socket.send(packet);

        socket.close();
    }
    //接收端
    @Test
    public void reciver() throws IOException {
        DatagramSocket socket = new DatagramSocket(9090);

        byte[] buffer = new byte[100];

        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0,packet.getLength()));

        socket.close();
    }

五、URL编程

1、URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。

2、URL的5个基本结构:

格式:

<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表

例如:http://localhost:8080/examples/hello.txt?name=Tom

3、如何实例化:

URL url = new URL("http://localhost:8080/examples/hello.txt");

4、常用方法:

public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/examples/hello.txt");
        /*
            public String getProtocol( ) 获取该URL的协议名
           public String getHost( ) 获取该URL的主机名
            public String getPort( ) 获取该URL的端口号
         public String getPath( ) 获取该URL的文件路径
           public String getFile( ) 获取该URL的文件名
           public String getQuery( ) 获取该URL的查询名
         */
        System.out.println(url.getProtocol());
        System.out.println(url.getHost());
        System.out.println(url.getPort());
        System.out.println(url.getPath());
        System.out.println(url.getFile());
        System.out.println(url.getQuery());
    }

5、可以读取、下载对应的url资源:

public static void main(String[] args){
        HttpURLConnection urlConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL("http://localhost:8080/examples/lvdi.jpeg");

            urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.connect();

            is = urlConnection.getInputStream();
            fos = new FileOutputStream("day10\\绿地3.jpeg");

            byte[] buffer = new byte[20];
            int len;
            while((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
            System.out.println("下载完成");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if(fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if(urlConnection != null){
                urlConnection.disconnect();
            }
        }
    }

五、小结

1、位于网络中的计算机具有唯一的IP地址,这样不同的主机可以互相区分。

2、客户端-服务器是一种最常见的网络应用程序模型。服务器是一个为其客户端提供某种特定服务的硬件或软件。客户机是一个用户应用程序,用于访问某台服务器提供的服务。端口号是对一个服务的访问场所,它用于区分同一物理计算机上的多个服务。套接字用于连接客户端和服务器,客户端和服务器之间的每个通信会话使用一个不同的套接字。TCP协议用于实现面向连接的会话。

3、Java 中有关网络方面的功能都定义在 java.net 程序包中。Java 用 InetAddress 对象表示 IP 地址,该对象里有两个字段:主机名(String) 和 IP 地址(int)。

4、类 Socket 和 ServerSocket 实现了基于TCP协议的客户端-服务器程序。Socket是客户端和服务器之间的一个连接,连接创建的细节被隐藏了。这个连接提供了一个安全的数据传输通道,这是因为 TCP 协议可以解决数据在传送过程中的丢失、损坏、重复、乱序以及网络拥挤等问题,它保证数据可靠的传送。

5、类 URL 和 URLConnection 提供了最高级网络应用。URL 的网络资源的位置来同一表示Internet 上各种网络资源。通过URL对象可以创建当前应用程序和 URL 表示的网络资源之间的连接,这样当前程序就可以读取网络资源数据,或者把自己的数据传送到网络上去

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

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

相关文章

【广度优先搜索遍历 + 染色法】判断二分图

还记得当时才大一&#xff0c;上离散数学课&#xff0c;当时觉得很不屑&#xff0c;就是觉得这学的什么玩弄啥用没有&#xff0c;但是其实很多的算法思想在解决题目时很有价值。 本文就将使用染色法解决判断二分图问题&#xff0c;使用广度优先搜索遍历和 Java 语言实现 一、题…

车辆逆行识别检测系统 opencv

车辆逆行识别检测系统通过opencvyolo网络深度学习技术&#xff0c;对现场画面中车辆逆向行驶行为进行检测抓拍预警。 OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一个跨平台的计算机视觉处理开源软件库&#xff0c;支持与计算机视觉和机器学习相关的众多…

嵌入式 LINUX 驱动开发 day02 字符设备驱动 字符设备驱动 虚拟串口, 一个驱动支持多个设备

1. 驱动开发 字符设备驱动 代码&#xff1a; vser.c #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h>#include <linux/fs.h> /***** 设备相关信息 ******/ static unsigned int VSER_MAJOR 256; //主设备号…

青铜到王者,9本最好的Python从入门到进阶的书

春节长假还有2周了&#xff0c;是时候囤一些书充充电了&#xff01;新的一年群里很多小伙伴开始想学Python&#xff0c; 无论是准备转行的&#xff0c;还是想多学一份技能提高职场竞争力的&#xff0c;都想选择Python赛道&#xff0c;下面给大家推荐一些非常不错的Python入门到…

【Flask框架】—— 30 Flask-RESTful

前后端分离和前后端不分离 前后端不分离 在前后端不分离的应用模式中&#xff0c;前端页面看到的效果都是由后端控制&#xff0c;由后端渲染页面或重定向&#xff0c;也就是后端需要控制前端的展示&#xff0c;前端与后端的耦合度很高。 这种应用模式比较适合纯网页应用&…

iclr 2022 Compositional attention: Disentangling search and retrieval

Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv preprint arXiv:2110.09419, 2021. 目录Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv p…

【Kettle报错】kettle7.0链接MySQL显示:No appropriate protocol

【Kettle7.0链接本地MySQL数据库报错】 1. 问题描述 报错问题&#xff1a;kettle7.0报错&#xff0c;提示No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 错误原因&#xff1a; Caused by: javax.net.ssl.SSLHandshakeException: No a…

Vue实现路由(Vue-router,参数传递,编程式路由导航)

目录 路由是什么&#xff1f; 怎么实现路由 第一步 创建一个文件夹 router &#xff0c;里面创建一个index.js 内容是 第二步 在main.js中引入和应用 router 第三步 在Vue中 通过两个标签进行配置 跳转路由时的参数传递 query params query参数和 param参数的区别 编…

原型链和JSON

对象的封装、继承和多态 封装、继承和多态是面向对象编程的三大特征&#xff0c;在JavaScript中也可以使用这些特征来实现面向对象的的编程。 封装是指将对象的属性和方法封装在对象内部&#xff0c;只提供必要的接口给外部访问。封装可以让我们隐藏对象的实现细节&#xff0c;…

项目管理:制定项目进度计划的好处有哪些?

项目管理计划确定了项目执行、监控及结束项目的整个过程&#xff0c;在项目开始之前&#xff0c;如能制定清晰的计划&#xff0c;并让项目成员都了解项目的目标和自己的责任&#xff0c;会对项目的推进有很大的帮助。 制定项目进度计划的好处有哪些&#xff1f; 1、目标导向…

高级树结构之二叉查找树

文章目录一 二叉查找树简介二 创建和插入操作三 查找操作3.1 查找思路3.2 代码实现四 删除操作4.1 情况讨论4.2 代码实现五 完整代码5.1 二叉查找树的结构5.2 完整代码内容一 二叉查找树简介 二叉查找树【二叉搜索树或是二叉排序树】 左子树中所有结点的值&#xff0c;均小于其…

(十一)devops持续集成开发——jenkins流水线发布一个docker harbor仓库版的前端vue项目

前言 本节内容&#xff0c;我们使用jenkins的流水线功能发布一个docker harbor私服仓库版的前端vue项目&#xff0c;延续前一节的内容&#xff0c;这里需要我们事先安装好一个docker harbor仓库用来存放我们项目的镜像&#xff0c;前端项目依然是通过nginx基础镜像构建&#x…

关于时间复杂度什么是时间复杂度

文章目录简介常见的Big-Oh简介 精确的考虑程序运行时间会使得寸步难行&#xff0c;而且毫无意义&#xff0c;所以可以用一种“概量”的概念来衡量运行时间&#xff0c;称之为“时间复杂度”。 时间复杂度的定义&#xff1a; 在一个完全立项状态下的计算机中&#xff0c;我们定…

【Sql Server】数据库的表变量和临时表的区别,并通过变量表随机生成姓名

作者&#xff1a;小5聊 简介&#xff1a;一只喜欢全栈方向的程序员&#xff0c;欢迎咨询&#xff0c;尽绵薄之力答疑解惑 公众号&#xff1a;有趣小馆&#xff0c;一个有趣的关键词回复互动功能 效果 1、表变量 1.1、表变量基本信息 1&#xff09;表变量本质是一个变量 是SQ…

《啊哈算法》第一章典例+解析+代码

目录 一&#xff0c;计数排序 二&#xff0c;冒泡排序&#xff08;Bubble Sort&#xff09; 三&#xff0c;快速排序&#xff08;Quick Sort&#xff09; 四&#xff0c;桶排序&#xff08;Bucket Sort&#xff09; 五&#xff0c;小哼买书 从无到有掌握最基础的算法 多学…

react hooks 封装一个countDown 倒计时组件

开发技术 react , hooks , ts , taro 需求分析 需要一个可以按天&#xff0c;时&#xff0c;分和秒来进行倒计时的组件。 简单使用 注&#xff1a;主要逻辑请看 useCountDown import CountDown from /components/countDown; import { useEffect, useState } from react; i…

东宝商城项目(二)——flask-script模块、flask-migrate模块和项目日志配置

学习flask-script模块的使用 1、什么是flask-script flask-script是flask的一个扩展模块&#xff0c;Flask-Script的作用是可以通过命令行的形式来操作Flask。 2、安装flask-script pip install flask-script 3、flask-script的使用 例如有这样一种需求&#xff1a; 我们…

李彦宏开年定调“百度式创新”:反馈驱动,坚定技术

今天在百度热搜看到这么一条置顶话题&#xff0c;让我印象深刻&#xff1a;读懂中国经济的信心所在。 站在2023年起点&#xff0c;无论你是阳了、没阳&#xff0c;还是阳康了&#xff0c;之于个人、企业组织&#xff0c;都太需要信心和激励了。 点进去后是一篇来自《人民日报 …

小程序直播加速抢占电商流量先机

临近春节&#xff0c;到了购置年货的时候&#xff0c;相信有不少小伙伴被淘宝、拼多多、抖音等各大平台的直播卖货吸引。近年来&#xff0c;大家逐渐发现视频直播的影响力已经渗透到各行各业&#xff0c;通过直播带来的流量&#xff0c;不少商家赚得盆满钵满。视频直播这块流量…

Autosar MCAL-GPT配置及使用

文章目录前言GPTGptChannelConfigSetGptChannelIdGptChannelModeGptChannelTickFrequencyGptChannelTickValueMaxGptEnableWakeupGptNotificationGptChannelClkSrcRefGptAssignedHwUnitGptConfigurationOfOptApiServicesGptDeinitApiGptEnableDisableNotificationApiGptTimeEla…