Java网络编程(下)

White graces:个人主页

🙉专栏推荐:Java入门知识🙉

🙉 内容推荐:Java网络编程🙉

🐹今日诗词:姑苏城外寒山寺,夜半钟声到客船🐹


⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏

⛳️点赞 ☀️收藏⭐️关注💬卑微小博主🙏


目录

网络编程套接字

套接字

TCP和UDP区别

有连接和无连接

可靠和不可靠传输

面向字节流和面向数据报

全双工和半双工

UDP数据报套接字编程

回显服务器

服务端

客户端

公网IP和私网IP

字典服务器

美图分享


网络编程套接字

套接字

socket就是网络编程的套接字, 可以认为是网络编程API的统称

操作系统提供的套接字不止一种, 常见的三种

1. 流式套接字 -> 给TCP使用

2. 数据报套接字 -> 给UDP使用

3. Unix域套接字(很少使用了) -> 不能跨主机通信, 只能本地主机上的进程和进程通信

TCP和UDP协议都是传输层协议, 都是服务于应用层

但是这两协议的差别去很大, 因此我们需要两套API分别去使用它们

TCP和UDP区别

总结概括就是

TCP: 有连接, 可靠传输, 面向字节流, 全双工

UDP: 无连接, 不可靠传输, 面向数据报, 全双工

有连接和无连接

TCP有连接: 比如打电话, 电话打通了才能说话, 可以选择接听, 也可以不接听

UDP无连接: 发短信微信, 对方不需要接通, 可以直接发送

有连接的特点: 通信双方保存了对方的信息

无连接的特点: 通信双方不需要保存对方的信息

可靠和不可靠传输

可靠传输 != 绝对安全, 只是尽可能保持数据不会丢失, 传输的过程可能会出现丢包

丢包: A向B传输10个数据, 但是中途经过很多交换机和路由器, 到B手中可能只剩下9个数据流了

TCP可靠传输: 尽量保持数据在传输中不丢失

UDP不可靠传输: 传输数不管对方有没有收到, 反正我发了

可靠传输也是有代价的, 传输效率会大打折扣

面向字节流和面向数据报

TCP面向字节流: 传输数据的基本单位是字节, 文件操作就是字节流, 像水流一样, 文件读写都非常灵活, TCP也是如此

UDP面向数据报: 传输数据的基本单位是UDP数据报, 一次读写必须读写一个完整的数据报, 不能缺斤少两, 不能多读多写

网络传输数据的基本单位

有四个, 数据报, 数据段, 数据包, 数据帧, 但一般不会过于区分, 都是混着用, 毕竟他们都是传输数据的基本单位, 硬要区分的话就是下面这样

1. 数据报DataGram  (UDP传输的基本单位)

2. 数据段Segment  (TCP)

3. 数据包 Packet  (IP)

4. 数据帧 Frame   (数据链路层)

全双工和半双工

全双工: 一条链路能够进行双向通信

半双工: 一条链路只能进行单向通信

TCP和UDP都是全双工

全双工特点: 使用socket对象时, 既可以读(接收)又可以写(发送)

半双工特点: 不能同时读和写, 只能进行其中一项

UDP数据报套接字编程

DatagramSocket: 这个类用于UDP数据报进行网络通信

DatagramPacket: 这个类封装数据报的类, 相当于将数据报包装成了一个类

一个形象的例子理解二者区别: 

如果把UDP网络通信比作送快递的话, DatagramSocket相当于快递员, DatagramPacket相当于包裹 

DatagramSocket负责管理和创建套接字(相当于快递员), 可以用来接收或者发送数据报(包裹), DatagramPacket类用于封装要发送或者接收的信息及目标地址和端口信息(相当于包裹), 可以被DatagramSocket发送或者接收

DatagramSocket构造方法

DatagramSocket(int port) : port是手动指定的端口号, 大小在0-->65535

DatagramSocket() : 无参数版本, 系统会随机指定一个端口号

DatagramPacket构造方法

DatagramPacket( byte[] buf, int length ) : 表示创建了一个名为buf的缓冲区, DatagramPacket只能使用length长度的缓冲区大小, 这种写法很奇怪, 比如这样: 

为什么要有缓冲区: 

如果客户端请求直接发送给服务端, 数量非常多时, 服务端压力会非常大,IO会非常频繁

可能会导致服务器挂了, 如果有一个缓冲区, 服务器可以不用那么及时去处理请求

大大减轻了服务器的压力, 同时存在缓冲区, 可以降低客户端和服务端的耦合性

回显服务器

服务端

我们直接来看服务端代码, 我在代码里加了注释, 建议复制粘贴到自己的编译器去看

import java.io.IOException;
import java.net.*;

public class UDPSever {
    private DatagramSocket socket = null;
    public UDPSever(String IP, int port)  throws IOException {
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException{
        System.out.println("服务器, 启动!");
        while (true) {
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            //创建了一个4096大小的缓冲区, DatagramPacket能使用缓冲区的大小为4096

            socket.receive(requestPacket);
            //DatagramSocket接收请求, receive可能会出现异常, 网络请求和响应也IO的一种抛出IOException异常即可
            //如果没有请求, receive就会自动阻塞, 阻塞到客户端发送请求为止

            String request = new String(requestPacket.getData(),0, requestPacket.getLength());
            //这里就是解析数据了
            //由于数据报都是二进制数据,我们将他转化成字符串数据, 便于观察
            //getData()是获取整个缓冲区的数据, getLength()获取实际有效数据长度

            String response = responsemethod(request);
            //服务器响应请求

            DatagramPacket responsePacket  = new DatagramPacket(response.getBytes(),
                    0, response.getBytes().length,
                    requestPacket.getSocketAddress());
            //构建响应数据报, 将响应的数据封装成数据报, 然后由服务器发送
            //数据报包含: 有效数据内容, 客户端地址, 端口号
            //getSocketAddress()可以获取完整的套接字信息, 包括IP信息端口号
            //getAddress只获取IP信息

            socket.send(responsePacket);
            //将数据报发送会客户端

            System.out.printf("日志: [%s:%d] requset = %s response = %s\n",
                    requestPacket.getAddress(), requestPacket.getPort(), request, response);
            //打印日志, System.out.printf(),可以像C语言一样, 格式化输出
            //System.out.println("[%s:%d]\n", requestPacket.getAddress(), requestPacket.getPort());
            //sout以ln结尾的不能格式化输出代码, System.out.println("%d", 5);像这种写法就是错的

        }
    }

    private String responsemethod(String request) {
        return request;
        //因为这里是模拟客户端和服务端, 所以响应我们写的简单点
        //客户端发送什么, 我们就原封不动的发送回去, 这种方式叫回显
    }

    public static void main(String[] args) throws IOException {
        UDPSever udpSever = new UDPSever("127.0.0.1", 9090);
        udpSever.start();
    }
}

客户端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UDPClient {
    public DatagramSocket socket = null;
    private String SeverIP;//服务器的IP
    private int SeverPort;//服务器的端口号
    public UDPClient(String SeverIP, int SeverPort) throws SocketException {
        socket = new DatagramSocket();//系统随机分配客户端端口号
        //为什么不手动指定客户端端口号呢?因为服务器端口号固定,客户端才能找到,
        //如果服务器端口号经常变,就会非常麻烦,但是服务器并不需要关注客户端的端口号

        this.SeverIP = SeverIP;
        this.SeverPort = SeverPort;
    }

    public void start() throws IOException {
        System.out.println("客户端, 启动!");
        while (true) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入你要发送的请求: ");
            String request = scanner.next();

            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),
                    0, request.getBytes().length,
                    InetAddress.getByName(SeverIP), SeverPort);
            //构建请求数据报,包含有效数据, 服务器IP地址, 服务器端口号
            //SecerIP是字符串, 需要转成服务器能够识别的类型,
            // 我们也可以在创建IP的时候就传入InetAddress类型的,但这是给编译器看的,不方便我们理解

            socket.send(requestPacket);
            //客户端发送数据报到服务器

            DatagramPacket responsePacket= new DatagramPacket(new byte[4096], 4096);//用于存放响应信息
            socket.receive(responsePacket);//接收响应信息
            
            String response = new String(responsePacket.getData(), 0, responsePacket.getData().length);
            System.out.print(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UDPClient udpClient = new UDPClient("127.0.0.1", 9090);
        udpClient.start();
    }
}

运行结果

公网IP和私网IP

每台电脑都有对应的IP, 但这并不意味着你知道了对方的IP就可以随意连接对方, 必须是公网IP才能够连接对方,如果不是公网IP, 还要连接对方, 你就需要和服务器在同一个局域网下才可以, 有点类似于开热点

私网IP和公网IP概念

私网IP: 地址满足(1)   10.*开头

                           (2)   172.16 -- 172.31*开头

                           (3)    192.168.*开头

满足这些开头的IP地址是私网地址, 其余都是公网IP地址

字典服务器

字典服务器: 输入英文单词, 返回对应的中文单词

这个很好实现, 就是在前面的回显服务器的基础上, 将响应方法改一下即可

因此我们的字典服务器直接继承UDPSever服务器类即可,然后重新里面的回显方法

import java.io.IOException;
import java.util.HashMap;

public class UDPdictionarySever extends UDPSever {
    HashMap<String, String> dictionary = null;
    public UDPdictionarySever(String IP, int port) throws IOException {
        super(IP, port);
        dictionary = new HashMap<>();
        dictionary.put("hello", "你好");
        dictionary.put("world", "世界");
        dictionary.put("dog", "小狗");
        dictionary.put("cat", "小猫");
        dictionary.put("pig", "GGBond我的男神GGBond");
    }

    @Override
    public String responsemethod(String request) {
        return dictionary.getOrDefault(request, "该单词没有对应的中文");
    }

    public static void main(String[] args) throws IOException {
        UDPdictionarySever udPdictionarySever = new UDPdictionarySever("127.0.0.1", 9090);
        udPdictionarySever.start();
    }
}

注意事项

运行效果


美图分享

✨🎆谢谢你的阅读和耐心!祝愿你在编程的道路上取得更多的成功与喜悦!"🎆✨🎄

⭐️点赞收藏加关注,学习知识不迷路⭐️

🎉✔️💪🎉✔️💪🎉✔️💪🎉✔️💪🎉

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

👍😏⛳️点赞☀️收藏⭐️关注😏👍

🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️🙆‍♂️

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

es的总结

es的collapse es的collapse只能针对一个字段聚合&#xff08;针对大数据量去重&#xff09;&#xff0c;如果以age为聚合字段&#xff0c;则会展示第一条数据&#xff0c;如果需要展示多个字段&#xff0c;需要创建新的字段&#xff0c;如下 POST testleh/_update_by_query {…

PTA 计算矩阵两个对角线之和

计算一个nn矩阵两个对角线之和。 输入格式: 第一行输入一个整数n(0<n≤10)&#xff0c;第二行至第n1行&#xff0c;每行输入n个整数&#xff0c;每行第一个数前没有空格&#xff0c;每行的每个数之间各有一个空格。 输出格式: 两条对角线元素和&#xff0c;输出格式见样例…

音视频开发—H264码流组成

本文包含了编码过程的相关概念&#xff0c;如果不了解编码过程&#xff0c;请看这篇文章&#xff1a;H264相关概念和压缩原理详解 H.264视频编码标准将视频编码过程分为两个主要层次&#xff1a;视频编码层&#xff08;VCL, Video Coding Layer&#xff09;和网络抽象层&#x…

Vue:Bin Code Editor格式化JSON编辑器

最终效果如下图所示&#xff0c; Bin Code Editor安装 npm或yarn安装命令如下&#xff0c; npm i bin-code-editor -S # or yarn add bin-code-editor 组件注册 全局注册 在 main.js 中写入导入以下内容&#xff0c; import Vue from vue; import CodeEditor from bin-cod…

0、机器学习知识点

机器学习知识点 知识点汇总 知识点汇总 https://blog.csdn.net/seagal890/article/details/105352987 https://blog.csdn.net/fengdu78/article/details/115878843

el-table超过宽度强制显示滚动条

使用css强制显示&#xff1a; .el-table .el-table__body-wrapper::-webkit-scrollbar {display: block; }

看图猜成语微信小程序源码

后台可以自行设置关卡、等级、也可以一键部署&#xff0c; 开通流量主之后实现躺赚&#xff0c;你懂得。 个人号也可以开通&#xff0c;审核一次性必过。 类目选择 教育&#xff0c;源码仅供您参考&#xff01; 源码下载 https://download.csdn.net/download/huayula/8938579…

【RS】哨兵系列新网站无法下载的问题及解决办法(Sentinel-2)

最近有些小伙伴留言说哨兵数据无法下载&#xff0c;网站打开后会有一层蒙版&#xff0c;无法选取研究区等信息&#xff0c;今天就跟大家分享一下如何解决这个问题。还知道如何下载的小伙伴可以移步到之前的文章&#xff1a;【RS】欧空局Sentinel-2卫星数据下载(哨兵1、2、3、5P…

DNF手游6月5日更新亮点全解析!

在即将到来的6月5日更新中&#xff0c;《DNF手游》将迎来一系列令人振奋的新内容和玩法。本文将详细介绍本次更新的主要内容&#xff0c;包括新增的组队挑战玩法“罗特斯入门团本”&#xff0c;新星使宠物的推出&#xff0c;宠物进化功能的开放&#xff0c;以及六月下旬即将落地…

2023年03月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 有如下程序段: with open(mistakes.txt, w) as f:words =[believe,

解决:写路由文件时引入页面路径没有提示

1、首先安装插件&#xff1a; Path Autocomplete 2、配置settings.json 文件 复制下面代码到settings.json配置文件中&#xff1a; "path-autocomplete.pathMappings": {"": "${folder}/src/","views": "${folder}/src/views/&…

数据可视化每周挑战——中国高校数据分析

最近要高考了&#xff0c;这里祝大家金榜题名&#xff0c;旗开得胜。 这是数据集&#xff0c;如果有需要的&#xff0c;可以私信我。 import pandas as pd import numpy as np import matplotlib.pyplot as plt from pyecharts.charts import Line from pyecharts.charts impo…

先进的无人机GPS/GNSS模块解决方案

由于多星座支持和增强的信号接收能力&#xff0c;先进的GNSS模块提供了更高的精度和可靠性。集成传感器融合补偿信号中断&#xff0c;实现无缝导航。内置实时运动学(RTK)支持提供厘米级的定位精度。这些模块还优先考虑低功耗和紧凑的尺寸&#xff0c;确保更长的飞行时间和对无人…

入手戴尔R720,通过iDRAC查看系统信息

想入手服务器很久了&#xff0c;一直担心功耗太高&#xff0c;今天狠心搞了一台戴尔服务器R720。 需求 开虚拟机&#xff0c;核心数要多 学习以下 Windows云桌面AD域控office online serverubuntu试验机 随便折腾不怕玩坏 最好两个网口以上 稳定 四个以上硬盘位 ‍ 为什么是…

信号稳定,性能卓越!德思特礁鲨系列MiMo天线正式发布!

作者介绍 礁鲨系列天线&#xff0c;以其独特的外观设计和强大的性能&#xff0c;成为德思特Panorama智能天线家族的最新成员。这款天线不仅稳定提供5G、WIFI和GNSS信号&#xff0c;更能在各类复杂环境中展现出卓越的性能。它的设计灵感来源于海洋中的礁鲨&#xff0c;象征着力量…

计算机考研|408 值得选择吗?有哪些优势?

408当然非常值得报考&#xff0c;但是现在的408已经卷麻了&#xff01; 现在越来越多的学校改考408&#xff0c;光今年就有6所发布通知&#xff0c;宣布改考408&#xff0c;分别是&#xff1a; 这对考408的学生肯定是好消息&#xff0c;后面可能还会有学校陆续改考&#xff0c;…

SpringBoot项目实现自定义注解方式的接口限流

一&#xff0c;实现原理 该限流方式使用的是令牌桶算法&#xff0c;令牌桶算法是基于漏桶算法的一种改进&#xff0c;主要在于令牌桶算法能够在限制服务调用的平均速率的同时&#xff0c;还能够允许一定程度内的突发调用。 系统以固定的速率向桶中添加令牌当有请求到来时&#…

生态系统服务功能之土壤保持

大家好&#xff0c;今天我们开始新的生态系统服务功能模块&#xff0c;即土壤保持的相关内容介绍与计算。 土壤保持的定义 所谓土壤保持&#xff0c;指生态系统通过其结构与过程保护土壤&#xff0c;降低雨水的侵蚀能力&#xff0c;减少土壤流失&#xff0c;防止泥沙淤积的功…

JVMの内存泄漏内存溢出案例分析

1、内存溢出 内存溢出指的是程序在申请内存时&#xff0c;没有足够的内存可供分配&#xff0c;导致无法满足程序的内存需求&#xff0c;常见的内存溢出情况包括堆内存溢出&#xff08;Heap Overflow&#xff09;和栈溢出&#xff08;Stack Overflow&#xff09;&#xff1a; …

K210视觉识别模块学习笔记4: 训练与使用自己的模型_识别字母

今日开始学习K210视觉识别模块: 模型训练与使用_识别字母 亚博智能的K210视觉识别模块...... 固件库: maixpy_v0.6.2_52_gb1a1c5c5d_minimum_with_ide_support.bin 文章提供测试代码讲解、完整代码贴出、测试效果图、测试工程下载 这里也算是正式开始进入到视觉识别的领域了…