UDP数据报套接字编程入门

目录

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();
    }
}

运行结果:

 

小结 :


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

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

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

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

相关文章

nginx反向代理之缓存 客户端IP透传 负载均衡

一 缓存功能 缓存功能可以加速访问,如果没有缓存关闭后端服务器后,图片将无法访问,缓存功能默认关闭,需要开启。 相关选项: ​ proxy_cache zone_name | off; 默认off #指明调用的缓存,或关闭缓存机制;C…

【C++初阶】第四站:类和对象(下)(理解+详解)

前言: 本篇知识点:初始化列表、explicit关键字、static成员、友元、内部类、匿名对象、编译器的优化 专栏:C初阶 目录 再谈构造函数 1️⃣构造函数体赋值 2️⃣初始化列表 explicit关键字 static成员 1.static概念 2.static特性 面试…

Docker技术概论(4):Docker CLI 基本用法解析

Docker技术概论(4) Docker CLI 基本用法解析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

NC65 零预算控制规则 数据库表关系

NC65 零预算控制规则 数据库表关系 SELECT t1.createdby, t1.objname, t2.ctrlname, t2.pk_parent, t3.billtype, t3.nameidx, t3.pk_obj FROM tb_rule_formula t1 left join tb_ctrlformula t2 on t1.pk_obj t2.pk_parent left join tb_ctrlscheme t3 on t3.pk_ctrlformula …

Mysql安装教程

一、下载 点开下面的链接:https://dev.mysql.com/downloads/mysql/ 点击Download 就可以下载对应的安装包了, 安装包如下: 二、解压 下载完成后我们得到的是一个压缩包,将其解压,我们就可以得到MySQL 8.0.31 的软件本体了(就是一个文件夹…

Tomcat布署及优化-----JDK和Tomcat

1.Tomcat简介 Tomcat 是 Java 语言开发的,Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。一般来说&…

Vivado Vitis 2023.2 环境配置 Git TCL工程管理 MicroBlaze和HLS点灯测试

文章目录 本篇概要Vivado Vitis 环境搭建Vivado 免费标准版 vs 企业版Vivado Windows 安装Vivado 安装更新 Vivado 工程操作GUI 创建工程打开已有工程从已有工程创建, 重命名工程GUI导出TCL, TCL复原工程TCL命令 Vivado 版本控制BlinkTcl脚本新建导出重建工程纯Verilog BlinkTc…

抖音视频批量下载软件说明|视频采集挖掘工具

操作步骤如下: 打开抖音批量下载工具,进入软件界面的第一个选项卡页面。在搜索框中输入需要搜索的视频关键词,例如"汽车配件",然后点击"开启抓取"按钮开始搜索。软件将开始搜索并显示与关键词相关的视频内容…

祖传代码:历史的宝藏与现代的挑战

程序员是如何看待“祖传代码”的? 程序员眼中的“祖传代码”,就像一本古老而神秘的魔法书,藏着无穷的智慧和技巧,有些代码像家传宝贝,有些像祖传秘方。快来分享一下你遇到的“祖传代码”吧~ 一、祖传代码的历史与文…

算法------(13)KMP

例题:(1)AcWing 831. KMP字符串 。。其实写完也不太理解。。随便写点吧 KMP就是求next数组和运用next的数组的过程。相比传统匹配模式一次更新一单位距离的慢速方法,next数组可以让下表字符串一次更新n - next【n】个距离&#x…

三天学会阿里分布式事务框架Seata-seata事务日志mysql持久化配置

锋哥原创的分布式事务框架Seata视频教程: 实战阿里分布式事务框架Seata视频教程(无废话,通俗易懂版)_哔哩哔哩_bilibili实战阿里分布式事务框架Seata视频教程(无废话,通俗易懂版)共计10条视频&…

虚拟机中Linux的安装与初始化配置(更新时间24/3/1)

先问三个问题 vm虚拟机安装了吗?点击此处跳转虚拟机安装教程Linux镜像下载了吗?点击此处跳转Linux镜像下载教程新建Linux虚拟机配置了吗?点击此处跳转新建虚拟机的配置教程 顺序是:下载虚拟机–>下载Linux镜像–>新建Linux配…

python63-Python的循环之循环使用else

Python的循环都可以定义else代码块&#xff0c;当循环条件为False 时&#xff0c;程序会执行else代码块。如下代码示范了为while循环定义else代码块。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…

Verilog(未完待续)

Verilog教程 这个教程写的很好&#xff0c;可以多看看。本篇还没整理完。 一、Verilog简介 什么是FPGA&#xff1f;一种可通过编程来修改其逻辑功能的数字集成电路&#xff08;芯片&#xff09; 与单片机的区别&#xff1f;对单片机编程并不改变其地电路的内部结构&#xff0…

YOLOv9大幅度按比例减小模型计算量!加快训练!

一、代码及论文链接&#xff1a; 代码链接&#xff1a;GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 论文链接&#xff1a;https://github.com/WongKinYiu/yolov9/tree/main 二…

Docker容器与虚拟化技术:OpenEuler 使用 docker-compose 部署 LNMP

目录 一、实验 1.环境 2.OpenEuler 部署 docker-compose 3.docker-compose 部署 LNMP 二、问题 1.ntpdate未找到命令 2.timedatectl 如何设置时区与时间同步 3.php网页显示时区不对 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注Lin…

Visual Studio:指针和固定大小缓冲区只能在不安全的上下文中使用、 设置允许使用不安全代码(unsafe)

问题描述: 指针和固定大小缓冲区只能在不安全的上下文中使用 解决方案&#xff1a; 1、解决方案资源管理器-》选择项目-》右键-》属性 2、在生成窗口中&#xff0c;勾选“允许不安全代码” 3、再次“生成解决方案”即可

C语言基础17 判断

断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&#xff09;。 C 语言把任何非零和非空的值假定为 true&#xff0c;把零或 null 假定为 false。 下面是…

免费百度快速收录软件

在网站SEO的过程中&#xff0c;不断更新网站内容是提升排名和吸引流量的关键之一。而对于大多数网站管理员来说&#xff0c;频繁手动更新文章并进行SEO优化可能会是一项繁琐且耗时的任务。针对这一问题&#xff0c;百度自动更新文章SEO工具应运而生&#xff0c;它能够帮助网站管…

Maven面试题

以下是一些关于Maven的经典面试题以及它们的答案&#xff1a; 1、什么是Maven&#xff1f; Maven是一个项目管理工具&#xff0c;用于构建、管理、发布Java项目。 2、为什么要使用Maven而不是手动管理项目依赖&#xff1f; Maven提供了依赖管理、统一的构建、打包、文档生…