【Socket套接字编程】(实现TCP和UDP的通信)

news2024/9/23 13:25:02

🎇🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!
人生格言: 当你的才华撑不起你的野心的时候,你就应该静下心来学习!
欢迎志同道合的朋友一起加油喔 💪💪💪
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个🐒嘿嘿
谢谢你这么帅气美丽还给我点赞!比个心

目录

  • 1、什么是网络编程
  • 2、Socket套接字
    • 2.1、概念
    • 2.2、分类
  • 3、UDP数据报套接字编程
    • 3.1、API 介绍
      • 📚DatagramSocket
      • 📚DatagramPacket
      • 📚InetSocketAddress
    • 3.2、基于UDP的Socket通信

1、什么是网络编程

  • ⽹络编程 ,指⽹络上的主机 ,通过不同的进程 ,以编程的⽅式实现⽹络通信(或称为⽹络数据传输)。

在这里插入图片描述

当然 ,我们只要满⾜进程不同就⾏;所以即便是同⼀个主机 ,只要是不同进程 ,基于⽹络来传输数 据 ,也属于⽹络编程。
特殊的 ,对于开发来说 ,在条件有限的情况下 ,⼀般也都是在⼀个主机中运⾏多个进程来完成⽹络编 程。
但是 ,我们⼀定要明确 ,我们的⽬的是提供⽹络上不同主机 ,基于⽹络来传输数据资源:
进程A:编程来获取⽹络资源
进程B:编程来提供⽹络资源

2、Socket套接字

2.1、概念

Socket套接字 ,是由系统提供⽤于⽹络通信的技术 ,是基于TCP/IP协议的⽹络通信的基本操作单元。 基于Socket套接字的⽹络程序开发就是⽹络编程。
操作系统提供的网络编程的API就称为 “ socket api ”

2.2、分类

  • Socket套接字主要针对传输层协议划分为如下三类:
  1. 流套接字:使⽤传输层-----------TCP协议
    TCP ,即Transmission Control Protocol(传输控制协议),传输层协议。 以下为TCP的特点(细节后续再学习):
  • 有连接
  • 可靠传输
  • ⾯向字节流
  • 全双工
  • 有接收缓冲区 ,也有发送缓冲区
  • ⼤⼩不限
    对于字节流来说 ,可以简单的理解为 ,传输数据是基于IO流 ,流式数据的特征就是在IO流没有关闭的 情况下 ,是⽆边界的数据 ,可以多次发送 ,也可以分开多次接收。
  1. 数据报套接字:使⽤传输层UDP协议
    UDP ,即User Datagram Protocol( ⽤户数据报协议),传输层协议。 以下为UDP的特点(细节后续再学习):
  • ⽆连接
  • 不可靠传输
  • ⾯向数据报
  • 全双工
  • 有接收缓冲区 ,⽆发送缓冲区
  • ⼤⼩受限:⼀次最多传输64k
    对于数据报来说 ,可以简单的理解为 ,传输数据是⼀块⼀块的 ,发送⼀块数据假如100个字节 ,必须⼀ 次发送 ,接收也必须⼀次接收100个字节 ,⽽不能分100次 ,每次接收1个字节。
  1. Unix 域套接字 -------不能跨主机通信,只能本机上的进程和进程之间的 通信

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、UDP数据报套接字编程

3.1、API 介绍

📚DatagramSocket

  • 系统中,本身就有socket这样的概念,DatagramSocket就是对于操作系统的socket概念的封装

  • 系统中的socket,可以理解成是一种文件

  • 文件是一个广义的概念~~

  • socket文件,就可以视为是"网卡"这种硬件设备的抽象表现形式.

  • 针对socket文件的读写操作就相当于针对网卡这个硬件设备进行读写.

  • 此处,DatagramSocket就可以视为是"操作网卡"的遥控器.
    针对这个对象进行读写操作,就是在针对网卡进行读写操作.

DatagramSocket是UDP Socket ,⽤于发送和接收UDP数据报

  • DatagramSocket构造方法:
方法签名方法说明
DatagramSocket()创建⼀个UDP数据报套接字的Socket ,绑定到本机任 意⼀个随机端⼝ ( ⼀般⽤于客户端)
DatagramSocket(int port)创建⼀个UDP数据报套接字的Socket ,绑定到本机指 定的端⼝ ( ⼀般⽤于服务端)
  • DatagramSocket 方法:
方法签名方法说明
void receive(DatagramPacket p)从此套接字接收数据报(如果没有接收到数据报 ,该 ⽅法会阻塞等待)
voidsend(DatagramPacket p)从此套接字发送数据报包(不会阻塞等待 ,直接发 送)
void close()关闭此数据报套接字

📚DatagramPacket

DatagramPacket是UDP Socket发送和接收的数据报。
Datagram Packet 构造方法:

方法签名方法说明
DatagramPacket(byte[] buf, int length)构造⼀个DatagramPacket以⽤来接收数据报 ,接收的 数据保存在字节数组(第⼀个参数buf) 中 ,接收指定 ⻓度(第⼆个参数length)
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造⼀个DatagramPacket以⽤来发送数据报 ,发送的 数据为字节数组(第⼀个参数buf) 中 ,从0到指定⻓ 度(第⼆个参数length)。address指定⽬的主机的IP 和端⼝号
  • Datagram Packet 方法:
方法签名方法说明
InetAddress getAddress()从接收的数据报中 ,获取发送端主机IP地址;或从发 送的数据报中 ,获取接收端主机IP地址
int getPort()从接收的数据报中 ,获取发送端主机的端⼝号;或从 发送的数据报中 ,获取接收端主机端⼝号
byte[] getData()获取数据报中的数据

构造UDP发送的数据报时 ,需要传⼊SocketAddress, 该对象可以使⽤InetSocketAddress来创建。

📚InetSocketAddress

InetSocketAddress(SocketAddress的⼦类 )构造⽅法:

⽅法签名⽅法说明
InetSocketAddress(InetAddress addr, int port)创建⼀个Socket地址 ,包含IP地址和端⼝号

3.2、基于UDP的Socket通信

步骤分析:

  1. 服务器端先启动,创建DatagramSocket对象,监听端口,用于接收
  2. 服务器端创建DatagramPacket对象,打包用于接收的数据包
  3. 服务器阻塞等待接收
  4. 客户端启动,创建DatagramSocket对象,监听端口,用于接收
  5. 客户端创建DatagramPacket对象,打包用于发送的数据包
  6. 客户端发送数据,服务端接收
  7. 服务端接收数据后,创建DatagramPacket对象,打包用于发送的数据包,发送数据
  8. 客户端创建DatagramPacket对象,打包用于接收的数据包,阻塞等待接收
  9. 客户端接收服务端数据,断开连接,释放资源
  • java中使⽤UDP协议通信 ,主要基于DatagramSocket类来创建数据报套接字 ,并使⽤DatagramPacket作为发送或接收的UDP数据报。对于⼀次发送及接收UDP数据报的流程如下:
    在这里插入图片描述
  • 以上只是⼀次发送端的UDP数据报发送 ,及接收端的数据报接收 ,并没有返回的数据。也就是只有请求 ,没有响应。对于⼀个服务端来说 ,重要的是提供多个客户端的请求处理及响应 ,流程如下:
    在这里插入图片描述

服务器端:

package network;
//其他的网络编程的类 都在 net 这个包中
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

//服务器程序,需要在程序启动的时候,将端口号确定下来
//原因:
//因为客户端是主动的一方,服务器是被动的一方
//所以呢?
//客户端要能知道服务器在哪,才能  “主动的了”
//需要知道哪些东西呢?
// 1、ip地址(服务器所在主机的ip)
// 2、端口号(一个主机上,有多个程序都要进行网络通信,就需要把哪个程序用哪个端口给明确下来)
//而且一个端口不能同时被两个或者多个进程来关联~~(不能重复)
public class UdpEchoServer {
    //对于一个服务器,一上来我们需要做什么工作呢?
    //我们要进行网络通信,呢就需要操纵网卡
    //而操纵网卡就是基于 socket 对象进行展开的
    //接下来实例化一个类作为 UdpEchoServer 这个服务器的成员变量
    private DatagramSocket socket = null;
    //SocketException异常继承于IOException
    //说明网络编程也属于 io 操作
    //io 是一个很广泛的概念
    public UdpEchoServer(int port) throws SocketException {
        //在构造方法里面进行实例化
        //一方面可以处理异常,另一方面还需要传入一个参数  (端口号)
        this.socket = new DatagramSocket(port);

    }
    //服务器还需要不停的去处理请求,不停的返回响应  期限(7 * 24)

    public void start() throws IOException {
        System.out.println("服务器启动!!!");
        while (true){
            //1)读取请求并解析
            byte[] bytes = new byte[4096];//“空盘子”
            //接受的数据保存在 数组里面
            //requestPacket 这个对象是一个UDP数据报
            //里面就包含两个部分:
            //1)报头(通过类的属性来表示)
            //2)载荷(通过构造方法传递的字符数组,作为持有载荷的空间)
            DatagramPacket requestPacket = new DatagramPacket(bytes,4096);
            /*
            括号里面需要填写输出型参数
            从此套接字接收数据报(如果没有接收到数据报 ,该⽅法会阻塞等待)
             */
            socket.receive(requestPacket);
            //此时requestPacket里面存储的是二进制数据,为了方便Java代码中处理,可以把上述数据报中的二进制数据,拿出来,构造为String
            String requst = new String(requestPacket.getData(),0,requestPacket.getLength());
            //2)根据请求计算响应
            //可以写成一个单独的方法
            String response = process(requst);

            //3)把响应写会到客户端
            //要想发送,也需要实例化一个 DatagramPacket 对象
            //括号里面需要放一个有数据的字节数组
            DatagramPacket responsePacket = new DatagramPacket(
                    response.getBytes(),
                    0,
                    response.getBytes().length,
                    requestPacket.getSocketAddress());
            /*
            requestPacket.getSocketAddress()
            这个方法返回的对象里面就包含了 IP 和 端口号
             */
            socket.send(responsePacket);
            //打印个日志
            //IP地址、端口号、请求、响应
            System.out.printf("[%s:%d] req = %s,resp = %s\n",
                    requestPacket.getAddress(),
                    requestPacket.getPort(),
                    requst,
                    response);
        }
    }
    //由于当前写的是“回显服务器”
    //请求和响应是一样的
    //所以 请求是什么,响应就返回什么
    private String process(String requst) {
        return requst;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}

UdpEchoServer(UDP 服务器):

  1. 首先,创建一个 DatagramSocket 对象,并绑定到指定的端口。这个端口用于服务器与客户端之间的通信。
  2. 在服务器的主循环中,首先创建一个空的 DatagramPacket 对象,用于接收客户端发来的请求数据。
  3. 调用 socket.receive(requestPacket) 方法接收客户端发来的数据包。
  4. 将收到的数据包中的数据转换成字符串形式,并调用 process() 方法生成响应。在这个例子中,响应就是原请求。
  5. 创建一个新的 DatagramPacket 对象,包含响应数据和客户端的地址信息。
  6. 使用 socket.send(responsePacket) 方法将响应数据包发送回客户端。
  7. 打印请求和响应信息。

客户端:

package network;

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

public class UdpEchoClient {
    //客户端和服务器一样
    //刚开始也需要创建 DatagramSocket 对象
    //接下来要对网卡进行操作
    //就需要借助 socket 这个 “遥控器”
    private DatagramSocket socket = null;
    private String severIp;
    private int severPort;
    //需要只要服务器的ip和端口号
    //通过额外的途径进行获取
    //利用String severIp,int severPort 来获取
    //因此服务器的IP和端口号不能老变
    public UdpEchoClient(String severIp,int severPort) throws SocketException {
        this.socket = new DatagramSocket();
        this.severIp = severIp;
        this.severPort = severPort;
    }

    public void start() throws IOException {
        System.out.println("客户端启动!!!");
        Scanner scanner = new Scanner(System.in);
        while (true){
            //1.让用户从控制台进行输入,发送给服务器
            System.out.println("请输入要发送的请求:");
            String request = scanner.next();
            //2.构造请求并发送
            //先实例化一个 DatagramPacket 对象 (数据报)
            // 不光要有数据   还要有目标 就是你要发给哪个服务器的哪个端口 也需要在这写出来
            // severIp = 127.0.0.1
            // 但是  InetAddress.getByName(severIp) 需要把 severIp 转换成一个Java能识别的对象
            //  转换成 InetAddress 这个对象 (系统能识别的IP地址)
            DatagramPacket requestPacket = new DatagramPacket(
                    request.getBytes(),
                    0,
                    request.getBytes().length,
                    InetAddress.getByName(severIp),
                    severPort
            );
            socket.send(requestPacket);

            //3.读取响应数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);

            //4.显示响应到 控制台上
            String response = new String(responsePacket.getData(),0, responsePacket.getLength());
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        // 使用后 127.0.0.1 是因为服务器和客户端在同一个主机上
        // 此时就固定写这个ip
        // 它又叫做 环回ip  系统提供的特殊ip
        UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
        //客户端的端口号 是操作系统自动进行分配的
        client.start();
    }
}

UdpEchoClient(UDP 客户端):

  1. 创建一个 DatagramSocket 对象,不需要显式地关联端口,系统会自动分配一个空闲的端口。
  2. 在客户端的主循环中,从控制台读取用户输入的字符串作为请求。
  3. 创建一个 DatagramPacket 对象,包含请求数据、服务器的 IP 地址和端口信息。
  4. 调用 socket.send(requestPacket) 方法将请求数据包发送给服务器。
  5. 创建一个空的 DatagramPacket 对象,用于接收服务器返回的响应数据。
  6. 调用 socket.receive(responsePacket) 方法接收服务器发来的响应数据包。
  7. 将收到的响应数据包中的数据转换成字符串形式,并打印请求和响应信息。

总结:这两段代码实现了一个简单的 UDP 回显服务器和客户端。客户端将用户输入的请求数据通过 UDP 协议发送给服务器,服务器接收到请求后原样返回响应,客户端接收响应并打印信息。整个过程使用无连接的 UDP 协议进行通信。

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

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

相关文章

Ubuntu 24.04安装Jellyfin媒体服务器图解教程

使用 Jellyfin 等开源软件创建媒体服务器肯定能帮助您管理和跨各种设备传输媒体集合。当你有一个封闭社区时,这尤其有用。 什么是 Jellyfin 媒体服务器? Jellyfin 媒体服务器,顾名思义,是一款开源软件,允许用户使用本…

高通Android 12 设置Global属性为null问题

1、最近在做app调用framework.jar需求&#xff0c;尝试在frameworks/base/packages/SettingsProvider/res/values/defaults.xml增加属性 <integer name"def_xxxxx">1</integer> 2、在frameworks\base\packages\SettingsProvider\src\com\android\provide…

mac环境下安装python3的图文教程

Python 是一种功能多样且强大的编程语言&#xff0c;在各个领域得到广泛应用。许多 Mac 用户都在其设备上安装和运行 Python&#xff0c;以运行特定的应用程序或创建、运行自己的 Python 脚本。 文章源自设计学徒自学网-http://www.sx1c.com/49441.html 虽然某些版本的 macOS…

jmeter-beanshell学习11-从文件获取指定数据

参数文件里的参数可能过段时间就不能用了&#xff0c;需要用新的参数。如果有多个交易&#xff0c;读不同的参数文件&#xff0c;但是数据还是一套&#xff0c;就要改多个参数文件。或者只想执行参数文件的某一行数据&#xff0c;又不想调整参数文件顺序。 第一个问题目前想到…

《JavaSE》---12.<面向对象系列之(附:static关键字及final关键字)>

目录 系列文章目录 前言 一、static修饰成员变量 1.1简单描述&#xff1a; 1.2用static修饰的好处&#xff1a; 1.3属于类而不属于对象 1.4如何访问更加合理&#xff1a; 1.5按static的修饰来分类 小结&#xff1a; 二、static修饰成员方法 2.1简单描述&#xff1a;…

openlayers 3d 地图 非三维 立体地图 行政区划裁剪 地图背景

这是实践效果 如果没有任何基础 就看这个专栏&#xff1a;http://t.csdnimg.cn/qB4w0 这个专栏里有从最简单的地图到复杂地图的示例 最终效果&#xff1a; 线上示例代码&#xff1a; 想要做这个效果 如果你的行政区划编辑点较多 可能会有卡顿感 如果出现卡顿感需要将边界点相应…

分布式IO系统2通道串口通信模块M602x

现场总线耦合器本身包含一个电源模块&#xff0c;它有 2 个串口通道&#xff0c;通过 Modbus RTU&#xff08;Master&#xff09;协议连接外部串行设备&#xff0c;实现耦合器与外部串行设备通信&#xff0c;现以连接设备的示例带大家了解我们钡铼的2 通道串口通信模块 M602x。…

使用llama-cpp-python制作api接口

文章目录 概要整体操作流程技术细节小结 概要 使用llama-cpp-python制作api接口&#xff0c;可以接入gradio当中&#xff0c;参考上一节。 llama-cpp-python的github网址 整体操作流程 下载llama-cpp-python。首先判断自己是在CPU的环境下还是GPU的环境下。以下操作均在魔搭…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-支持VForm3表单的选择与支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、初始化的时候加载表单 /** 查询表单列表 */ const getFormList () > {listForm().then(res > formOptions.value res.result.records) } 2、开始节点的修改&#xff0c;增加表…

JavaSE从零开始到精通

1.前置知识 JVM&#xff1a;java virtrual machine, java虚拟机, 专门用于执行java代码的一款软件。可以将class文件&#xff0c;转换为机器认识的机器码&#xff0c;因为我们的计算机只认识010101的二进制语言。JRE&#xff1a;java runtime enviroment, java运行时环境, jav…

人工智能算法工程师(中级)课程15-常见的网络模型及设计原理与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程15-常见的网络模型及设计原理与代码详解。 本文给大家介绍常见的网络模型及其设计原理与代码实现&#xff0c;涵盖了LeNet、AlexNet、VggNet、GoogLeNet、InceptionNet、ResNet、Dense…

【PostgreSQL】Windows 上安装 PostgreSQL 16版本

博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…

ubuntu24.04 linux bcm94352hmb 无线网卡(带蓝牙功能)无法连接蓝牙设备的解决办法

ubuntu24.04 linux bcm94352hmb 无线网卡&#xff08;带蓝牙功能&#xff09;无法连接蓝牙设备的解决办法 问题描述 小本是自己换装的bcm94352hmb&#xff0c;现在跑不动黑苹果了&#xff0c;换装ubuntu&#xff0c;该网卡在黑苹果上和windows上都能正常工作&#xff0c;到了…

怎样减少视频的容量 怎样减少视频内存保持清晰度

在数字媒体时代&#xff0c;视频内容已经成为人们日常交流和信息传递的重要方式。然而&#xff0c;视频往往占用大量存储空间&#xff0c;给我们的设备带来不小的负担。如何在不损失视频质量的前提下&#xff0c;减少视频文件的大小呢&#xff1f;本文将为你揭秘几个实用的技巧…

一文掌握Prometheus实现页面登录认证并集成grafana

一、接入方式 以保护Web站点的访问控制&#xff0c;如HTTP 服务器配置中实现安全的加密通信和身份验证&#xff0c;保护 Web 应用程序和用户数据的安全性。 1.1 加密密码 通过httpd-tools工具包来进行Web站点加密 yum install -y httpd-tools方式一&#xff1a;通过htpasswd生…

Postfix+Dovecot+Roundcube开源邮件系统搭建系列1-2:系统搭建目标+MariaDB数据库配置(MySQL)

1. 系统搭建目标 通过本系列文章&#xff0c;最终可以部署一套提供如下服务的邮件系统&#xff1a; SMTP服务&#xff1a;由Postfix提供&#xff0c;监听25、465、587端口。POP3服务&#xff1a;由Dovecot提供&#xff0c;监听110、995端口。IMAP服务&#xff1a;由Dovecot提…

TCP与UDP网络编程

网络通信协议 java.net 包中提供了两种常见的网络协议的支持: UDP&#xff1a;用户数据报协议(User Datagram Protocol)TCP&#xff1a;传输控制协议(Transmission Control Protocol) TCP协议与UDP协议 TCP协议 TCP协议进行通信的两个应用进程&#xff1a;客户端、服务端 …

(算法)区间调度问题

问题大致如下所述&#xff1a;有n项工作,每项工作分别在s时间开始,在t时间结束. 对于每项工作,你都可以选择参与与否,如果选择了参与,那么自始至终都必须全程参与. 此外,参与工作的时间段不能重复(即使是开始的瞬间和结束的瞬间的重叠也是不允许的). 你的目标是参…

数据结构历年考研真题对应知识点(哈夫曼树和哈夫曼编码)

目录 5.5.1哈夫曼树和哈夫曼编码 1.哈夫曼树的定义 2.哈夫曼树的构造 【分析哈夫曼树的路径上权值序列的合法性&#xff08;2010&#xff09;】 【哈夫曼树的性质&#xff08;2010、2019&#xff09;】 3.哈夫曼编码 【根据哈夫曼编码对编码序列进行译码&#xff08;201…

全文翻译 | OWASP《LLM安全与治理检查清单》

&#x1f4a1; 摘要&#xff1a; LLM AI Cybersecurity & Governace Checklist version 1.0 发布时间&#xff1a;2024年2月19日 本文是OWASP&#xff08;开放式网络应用安全项目&#xff09;发布的《LLM AI安全与治理清单》&#xff08;以下简称“清单”&#xff09;&…