Java学习_22_网络编程

news2024/12/24 8:34:09

文章目录

  • 前言
  • 网络编程
    • 网络编程三要素
      • IP
        • InetAddress
      • 端口号
      • 协议
      • OSI七层模型
      • TCP/IP模型
        • UDP协议
        • TCP协议
    • 综合练习
      • 多发多收
      • 接收和反馈
      • 上传文件
      • 上传文件重名问题
      • 上传文件多线程问题
      • 上传文件线程池问题
      • BS架构
  • 总结


前言

博客仅记录个人学习进度和一些查缺补漏。
学习内容:BV17F411T7Ao


网络编程

详见408《计算机网络》
在网络通讯协议下,不同的计算机上运行的程序进行数据传输。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

网络编程三要素

在这里插入图片描述

IP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述C类私有地址192.168.0.0
在这里插入图片描述
在这里插入图片描述

InetAddress

JAVA中提供的ip类,但是没有对外的构造方法,只有先获取自己的IP再更改。
例如:
在这里插入图片描述
也可以根据计算机名字获取:
在这里插入图片描述
例如:获取InetAddress对象
在这里插入图片描述

端口号

在这里插入图片描述
一个端口号只能被一个应用程序使用

协议

计算机网络中,连接和通信的规则被称为网络通信协议

在这里插入图片描述

OSI七层模型

在这里插入图片描述

TCP/IP模型

在这里插入图片描述

UDP协议

在这里插入图片描述
发送数据:
在这里插入图片描述
使用套接字DatagramSocket来发送信息,新建对象的时候需要绑定端口

例如:套接字就是快递小哥,具体的消息内容是将字符数组打包到DatagramPacket,并指定长度、地址和端口号然后,就像填写快递单一样。
在这里插入图片描述
接收数据:
在这里插入图片描述
例如:接收的时候一定要使用对应端口的快递小哥
接收数据也需要使用字符数组
在这里插入图片描述
注意,要先运行接收端,再运行发送端,接收方法receive会自动轮询阻塞等待接收消息,发送端口是随机指定的,并不需要手动指定。
在这里插入图片描述
例如:持续发送直到特殊信息出现
在这里插入图片描述
例如:持续接收
在这里插入图片描述
例如:重复运行多个当前类,形成聊天室
在这里插入图片描述
单播:1对1

组播:1对多

广播:1对全

在这里插入图片描述
例如:组播的实现,需要使用MulticastSocket组播套接字,并且发送的时候需要使用组播地址(组播地址详见计算机网络)

例如:组播的实现,需要让接收端的主机加入组播中
在这里插入图片描述

TCP协议

在这里插入图片描述
TCP再发送数据之前一定要建立连接

在这里插入图片描述
例如:客户端,发出数据(output)释放资源的时候要先关闭链接,再关闭客户端

在这里插入图片描述
例如:服务端,接收数据,会一直轮询accept方法等待链接。
在这里插入图片描述
注意,因为是通过字节流传输,没有指明编码表,所以接受中文的时候会出现乱码

需要在服务器中作出改动,将字节流变成字符流,即转换流
在这里插入图片描述
为增加阅读效率,可以再加入缓冲流

在这里插入图片描述
三次握手,四次挥手,详见408计算机网络。
在这里插入图片描述
在这里插入图片描述

综合练习

多发多收

在这里插入图片描述

package com.itheima.demo7;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientTest {
    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);

        Socket socket = new Socket("127.0.0.1", 10001);
        OutputStream os = socket.getOutputStream();

        // 发送数据
        while (true) {
            System.out.println("发送数据:");
            //注意这个\r\n只有在客户端读取整行时添加,第一种方法不用添加。
            String str = sc.nextLine() + "\r\n";
            if (str.equals("886")) {
                break;
            }
            os.write(str.getBytes());
        }

        os.close();
        socket.close();
    }
}

package com.itheima.demo7;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    public static void main(String[] args) throws IOException {
        //本机IP无需指定,只需要指定端口
        //ServerSocket就是本机专属快递员,Socket相当于管道,管道谁都能用,但管道送过来了还得指定的快递员来送达指定端口
        ServerSocket serverSocket = new ServerSocket(10001);

        Socket socket = serverSocket.accept();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //第一种单字读取
        /*int b;
        while ((b = bufferedReader.read()) != -1) {
            System.out.print((char) b);
        }*/
        //第二种整行读取
        String str = "";
        while ((str = bufferedReader.readLine()) != null){
            System.out.println(str);
        }

        socket.close();
    }
}

接收和反馈

在这里插入图片描述

package com.itheima.demo7;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class ClientTest {
    public static void main(String[] args) throws IOException {

        Scanner sc = new Scanner(System.in);

        Socket socket = new Socket("127.0.0.1", 10001);
        OutputStream os = socket.getOutputStream();

        // 发送数据
        while (true) {
            System.out.println("发送数据:");
            String str = sc.nextLine() + "\r\n";
            if (str.equals("886\r\n")) {
                break;
            }
            os.write(str.getBytes());
        }

        //结束标记
        socket.shutdownOutput();
        
        //接收反馈并输出
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String res = "";
        while ((res = bufferedReader.readLine()) != null) {
            System.out.println(res);
        }

        os.close();
        socket.close();
    }
}

package com.itheima.demo7;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    public static void main(String[] args) throws IOException {
        //本机IP无需指定,只需要指定端口
        //ServerSocket就是本机专属快递员,Socket相当于管道,管道谁都能用,但管道送过来了还得指定的快递员来送达指定端口
        ServerSocket serverSocket = new ServerSocket(10001);

        Socket socket = serverSocket.accept();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String str = "";
        while ((str = bufferedReader.readLine()) != null){
            System.out.println(str);
        }
        System.out.println("接收已结束");

        //发送反馈
        String res = "服务已结束\r\n";
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(res.getBytes());

        socket.close();
    }
}

上传文件

在这里插入图片描述

package com.itheima.demo7;

import java.io.*;
import java.net.Socket;

public class ClientTest {
    public static void main(String[] args) throws IOException {

        Socket socket = new Socket("127.0.0.1", 10001);

        // 发送文件数据
        String ori_path = "F:\\abc\\def\\aaa.jpg";
        File ori_file = new File(ori_path);
        sentFile(ori_file, socket);

        //接收反馈并输出
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String res = bufferedReader.readLine();
        System.out.println(res);

        socket.close();
    }

    public static void sentFile(File file, Socket socket) throws IOException {
        if(file.isFile()) {
            // 读取文件内容(buffer字节流)
            BufferedInputStream bfi = new BufferedInputStream(new FileInputStream(file));
            // 创建发送字节流
            BufferedOutputStream bfo = new BufferedOutputStream(socket.getOutputStream());

            int len;
            byte[] bytes = new byte[1024];
            while ((len = bfi.read(bytes)) != -1) {
                bfo.write(bytes, 0, len);
            }
            // 记住一定要刷新
            bfo.flush();

            //文件结束标记
            socket.shutdownOutput();
            //bfo.close();
        }
    }

}

package com.itheima.demo7;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    public static void main(String[] args) throws IOException {
        //本机IP无需指定,只需要指定端口
        //ServerSocket就是本机专属快递员,Socket相当于管道,管道谁都能用,但管道送过来了还得指定的快递员来送达指定端口
        ServerSocket serverSocket = new ServerSocket(10001);

        //持续监听,有人链接就把对方的套接字拿出来
        Socket socket = serverSocket.accept();

        //创建读者输入流
        BufferedInputStream bfi = new BufferedInputStream(socket.getInputStream());

        //创建写者输出流,指定位置
        BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream("F:\\abc\\bbb.jpg"));

        int len;
        byte[] bytes = new byte[1024];
        while ((len = bfi.read(bytes)) != -1) {
            bfo.write(bytes, 0, len);
        }
        //记住一定要刷新
        bfo.flush();

        System.out.println("接收已结束");

        //发送反馈
        String res = "服务已结束\r\n";
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(res.getBytes());

        socket.close();
        serverSocket.close();
    }
}

上传文件重名问题

在这里插入图片描述
使用UUID实现

        //创建写者输出流,指定位置
        String name = UUID.randomUUID().toString().replace("-", "");
        BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream("F:\\abc\\" + name +".jpg"));

上传文件多线程问题

在这里插入图片描述

package com.itheima.demo7;

import java.io.*;
import java.net.Socket;
import java.util.UUID;

public class ServerRunnable implements Runnable{

    private Socket socket;

    public ServerRunnable(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            // 创建读者输入流
            BufferedInputStream bfi = new BufferedInputStream(socket.getInputStream());

            // 创建写者输出流,指定位置
            String name = UUID.randomUUID().toString().replace("-", "");
            BufferedOutputStream bfo = new BufferedOutputStream(new FileOutputStream("F:\\abc\\" + name +".jpg"));

            int len;
            byte[] bytes = new byte[1024];
            while ((len = bfi.read(bytes)) != -1) {
                bfo.write(bytes, 0, len);
            }
            // 记住一定要刷新
            bfo.flush();

            System.out.println("接收已结束");

            // 发送反馈
            String res = "服务已结束\r\n";
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(res.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                if (socket != null){
                    socket.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

package com.itheima.demo7;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
    public static void main(String[] args) throws IOException {
        // 本机IP无需指定,只需要指定端口
        // ServerSocket就是本机专属快递员,Socket相当于管道,管道谁都能用,但管道送过来了还得指定的快递员来送达指定端口
        ServerSocket serverSocket = new ServerSocket(10001);

        while (true) {
            // 持续监听,有人链接就把对方的套接字拿出来
            Socket socket = serverSocket.accept();

            new Thread(new ServerRunnable(socket)).start();
        }

        // 服务器关闭
        //serverSocket.close();
    }
}

package com.itheima.demo7;

import java.io.*;
import java.net.Socket;

public class ClientTest {
    public static void main(String[] args) throws IOException {
		// 创建套接字
        Socket socket = new Socket("127.0.0.1", 10001);

        // 发送文件数据
        String ori_path = "F:\\abc\\def\\aaa.jpg";
        File ori_file = new File(ori_path);
        sentFile(ori_file, socket);

        // 接收反馈并输出
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String res = bufferedReader.readLine();
        System.out.println(res);

        socket.close();
    }

    public static void sentFile(File file, Socket socket) throws IOException {
        if(file.isFile()) {
            // 读取文件内容(buffer字节流)
            BufferedInputStream bfi = new BufferedInputStream(new FileInputStream(file));
            // 创建发送字节流
            BufferedOutputStream bfo = new BufferedOutputStream(socket.getOutputStream());

            int len;
            byte[] bytes = new byte[1024];
            while ((len = bfi.read(bytes)) != -1) {
                bfo.write(bytes, 0, len);
            }
            // 记住一定要刷新
            bfo.flush();

            // 文件结束标记
            socket.shutdownOutput();
            // 注意bfo是通过套接字创建的,关闭bfo会导致套接字关闭
            //bfo.close();
        }
    }

}

上传文件线程池问题

在这里插入图片描述

package com.itheima.demo7;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

public class ServerTest {
    public static void main(String[] args) throws IOException {
        //本机IP无需指定,只需要指定端口
        //ServerSocket就是本机专属快递员,Socket相当于管道,管道谁都能用,但管道送过来了还得指定的快递员来送达指定端口
        ServerSocket serverSocket = new ServerSocket(10001);

        // 定义线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3 // 最大核心线程数
        , 16 // 最大总线程数
        , 60 // 临时线程存活时间
        , TimeUnit.SECONDS // 时间单位
        , new ArrayBlockingQueue<>(3) // 等待队列大小
        , Executors.defaultThreadFactory()  // 线程工厂
        , new ThreadPoolExecutor.AbortPolicy()); // 阻塞队列处理方式

        while (true) {
            //持续监听,有人链接就把对方的套接字拿出来
            Socket socket = serverSocket.accept();

            //提交任务给线程队列(工会)
            threadPoolExecutor.submit(new ServerRunnable(socket));
        }
    }
}

BS架构

在这里插入图片描述

package com.itheima.demo7;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {
    public static void main(String[] args) throws IOException {

        // 创建服务器套接字
        ServerSocket ss = new ServerSocket(10001);
        // 监听等待套接字
        Socket s = ss.accept();

        // 有套接字连接后,接收套接字的输出
        BufferedInputStream bfi = new BufferedInputStream(s.getInputStream());

        int b;
        while ((b = bfi.read()) != -1) {
            System.out.print((char)b);
        }

        s.close();
        ss.close();
    }
}

总结

以前学套接字的时候完全搞不懂,怎么都写不出来就想着赶紧搞完赶紧出去玩,最后网上抄了一个,还不会运行,现在全心全意写代码学习感觉就完全不一样的,心态真的很关键。

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

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

相关文章

软考:一个月拿下软件设计师

前言 软考我满打满算也就准备了一个月不到&#xff0c;期间也走了不少弯路&#xff1b;特地做个博客记录一下&#xff0c;也给其它备考的人一些建议。 我是24年上半年参加的考试&#xff0c;说实在的这年下午题有几道不好写。 只要上午成绩和下午成绩都过45就算及格了。 正文…

【Git保姆级使用教程】Git从入门到精通超级详细的使用教程,一套教程带你搞定Git(高见龙版本)。

目录 Git下载与安装设置GitGit的用户设置 使用Git新增初始Repository将文件交给Git管控(将文件加入暂存区)查看Git文件记录查找commit记录更改提交commit的记录撤销提交commit 将某些文件取消Git版控Git中删除或更改文件名Git查看某个文件的某一行代码是谁写的.git目录中有什么…

Tower for Mac Git客户端管理软件

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试1、打开软件&#xff0c;测试2、克隆项目&#xff0c;测试 安装完成&#xf…

港股震荡中保持乐观,市场信心回来了!

港股上午盘三大指数集体上涨&#xff0c;恒生科技指数一度冲高至1.54%&#xff0c;最终收涨0.98%&#xff0c;恒生指数上涨1.06%。盘面上&#xff0c;大型科技股多数维持上涨行情&#xff0c;百度、腾讯涨超1.5%&#xff0c;快手、美团小幅上涨&#xff0c;阿里巴巴、京东飘绿&…

Java:Date类

文章目录 Date类常用方法代码演示 SimpleDateFormat常用方法代码演示时间格式常见符号SimpleDateFormat解析字符串为Date对象代码总结 案例&#xff1a;秒杀活动&#xff1a; 黑马学习笔记 这些方法在API文档都能查到 Date类 常用方法 代码演示 package Time;import java.uti…

杰发科技AC7801——Flash模拟EEP内存(2)

1. 默认配置在1000个地址存储1000个数据 配置如下 计算地址 查看地址内容&#xff0c;等到打印完成 计算符合&#xff0c;从0-999共计1000 2. 修改配置在65536地址存储65536个数据 配置还是这个 因为传进去的地址是uint16_t&#xff0c;因此最大值是65536&#xff0c;写65536…

mp总结 mybatisPlus

一、准备 1.引入依赖&#xff08;引入后可以不再引mybatis依赖&#xff09; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.2</version> </dependency> 2.…

Leetcode JAVA刷刷站(95)不同的二叉搜索数 ||

一、题目概述 二、思路方向 为了生成所有由 n 个节点&#xff08;值从 1 到 n&#xff09;组成的不同二叉搜索树&#xff08;BST&#xff09;&#xff0c;我们可以采用递归的方式。核心思想在于&#xff0c;对于每个数字 i&#xff08;从 1 到 n&#xff09;&#xff0c;我们可…

【C语言报错已解决】 `Buffer Overflow`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言一、问题描述&#x1f469;‍&#x1f52c;报错示例&#x1f4da;报错分析&#x1f4da;解决思路 二、解决方法&a…

麒麟V10(x86_64)安装部署MySQL-5.1.70

麒麟V10(x86_64)安装部署MySQL-5.1.70 1. 主机信息 [kalamikysrv1 ~]$ uname -a Linux kysrv1 4.19.90-24.4.v2101.ky10.x86_64 #1 SMP Mon May 24 12:14:55 CST 2021 x86_64 x86_64 x86_64 GNU/Linux [kalamikysrv1 ~]$ [kalamikysrv1 ~]$ uname -m x86_64 [kalamikysrv1 ~…

深度学习模板方法设计模式

文章目录 前言一、介绍二、特点三、详细介绍1.核心组成2.代码示例3.优缺点优点缺点 4.使用场景 总结 前言 模板方法设计模式是行为型设计模式&#xff0c;主要是定义算法框架&#xff0c;并将一些步骤的实现延迟到子类&#xff0c;重新定义算法的步骤。 一、介绍 模板设计模式…

项目初始化踩坑记录

dependence not found: D:/yupiProject/yubi-bi-frontend/node_modules/umijs/plugins/node_modules/react-intl 这个没有在github上找到解决方法&#xff0c;于是我在命令行 npm install 执行这个之后&#xff0c;就可以重新运行了 思考过程&#xff1a;突然空了个文件我…

开放式耳机是什么意思?开放式耳机推荐

在探讨音频设备的广阔领域中&#xff0c;开放式耳机以其独特的设计理念和卓越的性能体验&#xff0c;逐渐成为耳机市场上一股不可忽视的力量。顾名思义&#xff0c;开放式耳机是一种采用开放式设计&#xff0c;不堵塞或覆盖耳朵&#xff0c;允许佩戴者同时听到部分外部声音的耳…

Unity滚滚车轮计划 之 新输入系统控制2D角色移动动画(俯视)

本系列的初衷是因为很多时候基础代码不得不重复又重复&#xff0c;所以为了更快更好地学习到新的知识&#xff0c;我就把已经掌握的知识造成自己的轮子吧&#xff0c;等用到的时候直接复制就行了 叠甲&#xff1a;虽然不能保证全是原创&#xff0c;有些写法可能烂大街&#xff…

arm64--内嵌汇编

内嵌汇编代码基本用法 1.作用&#xff1a;对于特定重要和时间敏感的代码进行优化&#xff0c;同时在C语言中访问某些特殊指令&#xff08;例如内存屏障指令&#xff09;来实现特殊功能 2.内嵌汇编代码主要有两种形式 基础内嵌汇编代码&#xff1a;不带任何参数 扩展内嵌汇…

【ES6新特性】介绍ES6新特性的内容,如var,Let,Const声明变量的区别,解构赋值的概念,字符串的扩展,数组的扩展,以及对象的扩展。

目录 1.var&#xff0c;let&#xff0c;const的区别 1.1 var 1.2 let 1.3 const 1.4 区别总结 2.解构赋值 2.1 基本解构化赋值 2.2 数组取值 2.3 对象解构化赋值和取值 2.4 Math对象的解构化使用 3. 字符串扩展 3.1 新增字符串遍历方式 3.2 模版字符串 3.3 字符串…

数据库学习笔记

一、数据库相关概念 主流的关系型数据库管理系统&#xff08;DBMS&#xff09; 关系型数据库以 表格 的形式存在&#xff0c;以 行和列 的形式存取数据&#xff0c;关系型数据库这一系列的行和列被称为表&#xff0c;无数张表组成了 数据库 &#xff0c;常见的关系型数据库有 …

绿色积分引领:我店平台的可持续消费革命

在当今数字化浪潮的推动下&#xff0c;“我店”凭借其创新的环保积分系统&#xff0c;在消费市场中脱颖而出&#xff0c;逐渐改变着市场的结构。本文将详细分析该平台的竞争优势、市场策略以及它如何利用创新手段塑造未来的消费趋势。 一、环保积分&#xff1a;消费体验革新的关…

在ElementUI项目中集成iconfont图标库

在前端项目开发中经常会遇到使用的组件库提供的ICON图标不够用的情况。最常见的解决方案无非就是把设计图的图标切图引入到项目中。还有就是使用svg图标&#xff0c;封装一个渲染组件在项目里面直接引入这个组件。 本文将介绍另一种方法&#xff0c;即集成iconfont图标库的图标…

redis面试(二十二)读锁释放

假设现在已经有各种锁的重入什么的&#xff0c;那如何释放锁&#xff1f; 读锁读锁 假如说&#xff0c;同一个线程多次加读锁&#xff0c;或者不同的线程加了多个读锁 当前的锁结构长这样 anyLock: { “mode”: “read”, “UUID_01:threadId_01”: 2, “UUID_02:threadId_02…