UDP数据报套接字编程入门

news2024/10/7 20:28:40

目录

1.TCP和UDP的特点及区别

1.1TCP的特点

 1.2UDP的特点

 1.3区别

2.UDP Socket的api的介绍

2.1DatagramSocket API

2.2DatagramPacket API  

3.回显客户端与服务器

3.1回显服务器

3.1.1UdpEchoServer类的创建

3.1.2服务器的运行方法start()

3.1.3main部分

 3.1.4.完整代码

 3.2回显客户端

3.2.1UdpEchoClient类的创建

 3.2.2客户端的运行方法start()

3.2.3main部分 

3.2.4 完整代码


1.TCP和UDP的特点及区别

想要进行网络编程,都需要使用到系统的API。本质上都是传输层提供的。传输层涉及到的协议主要有两个。TCP和UDP,他俩的api差异很大。

TCP和UDP都是Socket套接字针对的传输层协议划。

Socket 套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议网络通信的基本操作单元。基 于Socket 套接字的网络程序开发就是网络编程

1.1TCP的特点

流套接字 :使用传输层 TCP 协议  
以下为TCP的特点
1.有连接
2.可靠传输
3.面向字节流
4.有接收缓冲区,也有发送缓冲区
5.大小不限
对于字节流来说,可以简单的理解为,传输数据是基于 IO 流,流式数据的特征就是在 IO 流没有关闭的情 况下,是无边界的数据,可以多次发送,也可以分开多次接收。

 1.2UDP的特点

数据报套接字:使用传输层UDP协议

以下为UDP的特点

1.无连接
2.不可靠传输
3.面向数据报
4.有接收缓冲区,无发送缓冲区
5.大小受限:一次最多传输 64k

 1.3区别

(1)有/无 连接

网络中谈到的连接,本质上是通信双方各自保存双方信息。

有连接是通信双方都要同意。如:微信发电话。

无连接是收方无论是否同意,都会收到信息。如:微信发消息。

(2)可/不可 靠传输

由于网络上存在的异常情况非常的多,无法保证网络数据100%通信成功。

可靠传输 是指发送方知道自己发送的信息是否成功送达。反之不知道则是不可靠传输

(3) 面向数据报/字节流

指的是网络中传输的基本单位是数据报/字节流。


2.UDP Socket的api的介绍

2.1DatagramSocket API

DatagramSocket UDP Socket,用于发送和接收UDP数据报。

socket 文件抽象了“网卡”这样的硬件设备。

(1)DatagramSocket 构造方法:

 (2)DatagramSocket 方法:

2.2DatagramPacket API  

DatagramPacketUDP Socket发送和接收的数据报。 

(1)DatagramPacket 构造方法:

 (2)DatagramPacket 方法:

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

InetSocketAddress API
InetSocketAddress SocketAddress 的子类 )构造方法:


3.回显客户端与服务器

什么叫回显客户端与与服务器呢?

其实就是:客户端向服务端发送请求,一般来说我们的服务端会对我们发送的请求进行处理,我们这里为了简单,就省略里面的处理过程,只实现将请求重新发回客户端,不做任何处理。

3.1回显服务器

3.1.1UdpEchoServer类的创建

1.需要创建一个DatagramSocket对象,因为需要操作网卡。

代码:

public class UdpEchoServer {
    private DatagramSocket socket=null;

    public UdpEchoServer(int port) throws SocketException {
        socket=new DatagramSocket(port);
    }
}

代码说明:

(1)socket=new DatagramSocket(port);

在运行一个服务器的时候,通常会手动指定一个端口号。

补:一个主机上的端口号,只能被一个进程绑定,但一个进程可以绑定多个端口号。 

(2)throws SocketException

通常表示socket创建失败。

比如:端口号已经被别的进程占用了。

3.1.2服务器的运行方法start()

工作内容:

1. 读取请求并解析

2. 根据请求计算响应 (对于 回显服务器来说, 这一步啥都不用做)

3. 把响应返回到客户端.

4.打印日志

 代码:

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


public class UdpEchoServer {
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true) {
            DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestpacket);
            String request = new String(requestpacket.getData(), 0, requestpacket.getLength());
            String response = process(request);
            DatagramPacket responsepacket = new DatagramPacket(response.getBytes(), response.getBytes().length, requestpacket.getSocketAddress());
            socket.send(responsepacket);
            // 打印日志
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestpacket.getAddress().toString(),
                    requestpacket.getPort(), request, response);
        }
    }

    private String process(String request) {
        return request;
    }
}

代码说明:

1.  while (true) {~~~}

对于服务器来说,需要不停的收到请求,返回响应,收到请求,返回响应

2.    DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);

(1)byte[4096]->4096 表示的是载荷长度。

这个数组存的是消息正文(应用层数据包)也就是UDP数据包载荷部分。

(2) socket.receive(requestpacket);

如果执行到socket.receive(requestpacket)的时候,还没有客户端发来请求,则会先堵塞等待。

(3 )requestpacket.getSocketAddress()

由于requestpacket是从客户端来的数据报,故得到的InetAddress对象就会包含了客户端的IP和端口号。

3.1.3main部分

代码:

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

代码说明:

UdpEchoServer server = new UdpEchoServer(9090);

9090->这个端口号可以指定任何你想要指定的端口号。

 3.1.4.完整代码

代码:

package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpEchoServer {
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    // 服务器的启动逻辑.
    public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true) {
            // 每次循环, 就是处理一个请求-响应过程.
            // 1. 读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(requestPacket);
            // 读到的字节数组, 转成 String 方便后续的逻辑处理.
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            // 2. 根据请求计算响应 (对于 回显服务器来说, 这一步啥都不用做)
            String response = process(request);
            // 3. 把响应返回到客户端.
            //    构造一个 DatagramPacket 作为响应对象
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);

            // 打印日志
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }
    }

    public String process(String request) {
        return request;
    }

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

 3.2回显客户端

3.2.1UdpEchoClient类的创建

代码:

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

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp;
    private int serverPort;

    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        this.socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
}

 代码说明:

(1)this.socket = new DatagramSocket();

客户端这边一般不会手动指定端口好,会让系统自动分配一个端口号。

(2)private String serverIp;
         private int serverPort; 

  客户端需要主动给服务器发送请求,发送请求的前提是知道服务器在哪。

 3.2.2客户端的运行方法start()

工作内容:

1. 从控制台读取要发送的请求数据.

2. 构造请求并发送

3. 读取服务器的响应.

4. 把响应显示到控制台上

代码:

 public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.print("->");
            if(!scanner.hasNext()){
                break;
            }
            String request=scanner.next();
            DatagramPacket requestpacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            socket.send(requestpacket);
            DatagramPacket responsepacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(responsepacket);
            String response=new String(responsepacket.getData(),0,responsepacket.getLength());
            System.out.println(response);
        }
    }

  代码说明:

InetAddress.getByName(serverIp)

把数据的单位从字符->字节。

3.2.3main部分 

代码:

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }
3.2.4 完整代码

代码:

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

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp;
    private int serverPort;


    // 此处 ip 使用的字符串, 点分十进制风格. "192.168.2.100"
    public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        socket = new DatagramSocket();
    }

    public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner scanner = new Scanner(System.in);
        while (true) {
            // 要做四个事情
            System.out.print("-> "); // 表示提示用户接下来要输入内容.
            // 1. 从控制台读取要发送的请求数据.
            if (!scanner.hasNext()) {
                break;
            }
            String request = scanner.next();
            // 2. 构造请求并发送.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serverIp), serverPort);
            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 {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        // UdpEchoClient client = new UdpEchoClient("139.155.74.81", 9090);
        client.start();
    }
}

运行结果:

 

小结 :


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

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

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

相关文章

LeetCode #104 二叉树的最大深度

104. 二叉树的最大深度 题目 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3 示例 2: 输入:root [1,null,2] 输出:2 分析 …

CMake、OpenCV 和单元测试

我写了很多关于 CMake 的文章,如果你感兴趣,可以点击以下链接阅读: CMake VS MakeCMake:在构建世界掀起风暴现代 CMake 使用技巧CMake 交叉编译CMake 生成器已开启 我们将继续对 CMake 的探索,这篇文章技术性高&…

云商大宗商品使用的是什么系统,有什么功能

云商大宗商品使用的系统主要包括大宗商品贸易系统、大宗商品仓储管理系统。 大宗商品贸易系统则是一种基于互联网技术的交易平台,旨在为买卖双方提供高效、安全、透明的交易环境。该系统具备商品管理、交易管理、资金管理、数据分析和风险管理等功能模块&#xff0…

2024年四川媒体新闻发布渠道,媒体邀约资源表

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 四川有哪些媒体新闻发布渠道,媒体邀约资源表? 2024年四川媒体新闻发布渠道,媒体邀约资源表 四川本地媒体:如四川日报、华西都市报、成都商…

2024年最好的 5 款免费的数据恢复软件

数据意外损坏或丢失?别担心,今天我为大家带来了实用的免费硬盘数据恢复软件! 在数字化时代,数据的重要性不言而喻。但是,由于种种原因,数据意外损坏或丢失的情况时有发生。此时,一款实用的免费…

SpringBoot 自定义映射规则resultMap association一对一

介绍 例:学生表,班级表,希望在查询学生的时候一起返回该学生的班级,而一个实体类封装的是一个表,如需要多表查询就需要自定义映射。 表结构 班级表 学生表 SQL语句 SELECT a.id,a.name,a.classes,b.id classes…

JS(JavaScript)中如何实现,复选框checkbox多选功能

起始界面&#xff1a; 代码元素&#xff1a; <p><input type"checkbox" id"checkedAll"> 全选按钮</p><p><input type"checkbox" class"cl"> 选项1</p><p><input type"checkbox&qu…

张驰咨询:为什么每个应届生都应该参加六西格玛培训?

应届生参加六西格玛培训的现象逐渐成为了一个新的趋势&#xff0c;这背后的原因不仅仅是市场对于品质管理人才的渴求&#xff0c;也源于应届生自身发展的需求。本文张驰咨询将从应届生的视角探讨参加六西格玛培训的动机&#xff0c;以及这种培训如何为他们的职业生涯铺路。 为…

认识通讯协议——TCP/IP、UDP协议的区别,HTTP通讯协议的理解

目录 引出认识通讯协议1、TCP/IP协议&#xff0c;UDP协议的区别2、HTTP通讯协议的讲解 Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 认识通讯协议——TCP/IP、UDP协议的区别&#xff0c;HTTP通讯协议的理解 认识通讯协议 …

做活动和会议直播,为什么要多个媒体平台同步直播?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 多个媒体平台同步直播活动和会议的原因主要有以下几点&#xff1a; 扩大观众覆盖面&#xff1a;不同的媒体平台拥有各自独特的用户群体&#xff0c;通过在多个媒体平台同步直播&#xff…

Unity(第二十一部)动画的基础了解(感觉不了解其实也行)

1、动画组件老的是Animations 动画视频Play Automatically 是否自动播放Animate Physics 驱动方式&#xff0c;勾选后是物理驱动Culling Type 剔除方式 默认总是动画化就会一直执行下去&#xff0c;第二个是基于渲染播放&#xff08;离开镜头后不执行&#xff09;&#xff0c; …

如何解决 C/C++ 编译器优化导致的编译BUG(程序崩溃)支援VC++/CLANG/GCC

本文仅适用于&#xff0c;有愿意、爱捣鼓的童靴。 因编译器优化导致编译BUG&#xff0c;即DEBUG下面无故障稳定工作&#xff0c;但RELESE下程序会在特定函数位置上崩溃。 这要求 C/C 开发人员拥有最基本的素质&#xff0c;需要能够承受&#xff0c;逐行审视编译器输出的目标平…

yolov9,使用自定义的数据训练推理

[源码 &#x1f40b;]( GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information) [论文 &#x1f4d8;](arxiv.org/pdf/2402.13616.pdf) 论文摘要&#xff1a;本文介绍了一种新的目标检测…

【 JS 进阶 】正则表达式

“生命是一幅抽象画&#xff0c;每一笔都是独特的经历。在色彩的交织中&#xff0c;用坚定的画笔勾勒出自己的轨迹&#xff0c;让每一幅画作都成为奋斗的印记。” - 亚历山大斯密斯 正则表达式 正则表达式&#xff08;Regular Expression&#xff09;是一种字符串匹配的模式&a…

二、TensorFlow结构分析(2)

目录 1、会话 1.1 __init__(target,graphNone,configNone) 1.2 会话的run() 1.3 feed操作 TF数据流图图与TensorBoard会话张量变量OP高级API 1、会话 1.1 __init__(target,graphNone,configNone) def session_demo():# 会话的演示# Tensorflow实现加法运算a_t tf.constan…

LNMP 架构

搭建 LNMP 架构需要安装 nginx mysql php 软件 linux nginx mysql php结合 在一台主机上搭建LNMP架构 一、编译安装 nginx 安装依赖包 yum -y install pcre-devel zlib-devel gcc gcc-c make 创建nginx程序用户 &#xff08;Nginx 服务程序默认以 nobody 身份运…

基于java Springboot实现课程评分系统设计和实现

基于java Springboot实现课程评分系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

MySQL(基础篇)——事务

一.事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作色一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 默认MySQL的事务是自动提交的&#xff0c;也就是说&#xff0c…

QML中动态增加表格数据

1.QML中的表格实现 import QtQuick 2.15 import QtQuick.Window 2.15import QtQuick.Controls 2.0 import Qt.labs.qmlmodels 1.0 import QtQuick.Layouts 1.15Window {width: 640height: 480visible: truetitle: qsTr("Hello World")TableModel{id:table_modelTabl…

STM32 IIC协议基础概念

文章目录 前言一、IIC协议介绍二、IIC硬件框图和程序层次三、IIC协议1.IIC协议通信流程2.IIC的引脚为什么需要加入上拉电阻3.IIC的引脚为什么需要配置为开漏输出 四、STM32 IIC硬件结构总结 前言 本篇文章将带大家学习IIC通信协议的一些基础概念和使用。 一、IIC协议介绍 I2…