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

运行结果:

 

小结 :


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

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

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

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

相关文章

C# CAD PaletteSet.Style各种外观和行为样式

ps.Style 是 Autodesk.AutoCAD.Windows.PaletteSet 类的一个属性,用于定义调色板集(PaletteSet)的各种外观和行为样式。它可以是 PaletteSetStyles 枚举类型的组合值 PaletteSetStyles 枚举中包含以下一些选项: NameEditable&am…

统计子矩阵

一、题目描述 P8783 [蓝桥杯 2022 省 B] 统计子矩阵 二、算法简析 2.1 二维前缀和 我们知道,只要确定了矩阵的左上顶点和右下顶点,一个矩阵就被固定了。因此,我们可以遍历这两个顶点,达到遍历所有子矩阵的目的,复杂…

在微服务整合dubbo,以为微服务版的若依为例

在微服务整合dubbo,以为微服务版的若依为例 一、环境二、整合过程1、父模块依赖2、生产者3、消费者 三、修改若依的服务调用方式为dubbo1、改造系统模块2、改造认证授权中心 四、整合过程遇到的问题1、出现循环引用2、出现依赖冲突3、启动出现端口号被占用4、出现某…

UVa11726 Crime Scene

题目链接 UVa11726 - Crime Scene 题意 给定n(n≤100)个物体,每个物体都是一个圆或者k(k≤10)边形,用长度尽量小的绳子把它们包围起来。 分析 孟加拉国Manzurur Rahman Khan (Sidky)大神出的难题&#xff…

MySQL 核心模块揭秘 | 07 期 | 二阶段提交 (1) prepare 阶段

二阶段提交的 prepare 阶段,binlog 和 InnoDB 各自会有哪些动作? 本文基于 MySQL 8.0.32 源码,存储引擎为 InnoDB。 1. 二阶段提交 二阶段提交,顾名思义,包含两个阶段,它们是: prepare 阶段。…

springboot-基础-eclipse配置+helloword示例

备份笔记。所有代码都是2019年测试通过的,如有问题请自行搜索解决! 下一篇:springboot-基础-添加model和controller的简单例子常用注解含义 目录 配置helloword示例新建项目创建文件 配置 spring boot官方有定制版eclipse,也就是…

BUUCTF AWD-Test1

打开靶场是这个有些简陋的界面。 随便点点,找到这个东西。 看到ThinkPHP,思路瞬间清晰,老熟人了。这个就是ThinkPHP漏洞。根据版本我们去找一下poc。 /index.php/?sIndex/\think\View/display&content%22%3C?%3E%3C?php%20phpinfo();…

服务端向客户端推送数据的实现方案

在日常的开发中,我们经常能碰见服务端需要主动推送给客户端数据的业务场景,比如数据大屏的实时数据,比如消息中心的未读消息,比如聊天功能等等。 本文主要介绍SSE的使用场景和如何使用SSE。 服务端向客户端推送数据的实现方案有哪…

MySQL 自增列解析(Auto_increment)

MySQL数据库为列提供了一种自增属性,当列被定义为自增时。Insert语句对该列即使不提供值,MySQL也会自动为该列生成递增的唯一标识,因此这个特性广泛用于主键的自动生成。 一、自增列的用法 自增列具有自动生成序列值,整型&#…

MYSQL04高级_逻辑架构剖析、查询缓存、解析器、优化器、执行器、存储引擎

文章目录 ①. 逻辑架构剖析②. 服务层 - 查询缓存③. 服务层 - 解析器④. 服务层 - 优化器⑤. 服务层 - 执行器⑥. MySQL8执行原理 ①. 逻辑架构剖析 ①. 服务器处理客户端请求 ②. 连接层 系统(客户端)访问MySQL服务器前,做的第一件事就是建立TCP连接经过三次握手建立连接成…

Linux使用C语言实现通过互斥锁限制对共享资源的访问

互斥锁限制共享资源的访问 主线程中有两个线程&#xff0c;分别输出信息。 #include <stdio.h> #include <pthread.h> #include <unistd.h>int g_data0;void* fun1(void *arg) {printf("t1&#xff1a;%ld thread is create\n", (unsigned long)…

稀疏图带负边的全源最短路Johnson算法

BellmanFord算法 Johnson算法解决的问题 带负权的稀疏图的全源最短路 算法流程 重新设置的每条边的权重都大于或等于0&#xff0c;跑完Djikstra后得到的全源最短路&#xff0c;记得要还原&#xff0c;即&#xff1a;f(u,v) d(u,v) - h[u] h[v] 例题

45、WEB攻防——通用漏洞PHP反序列化POP链构造魔术方法原生类

文章目录 序列化&#xff1a;将java、php等代码中的对象转化为数组或字符串等格式。代表函数serialize()&#xff0c;将一个对象转换成一个字符&#xff1b;反序列化&#xff1a;将数组或字符串等格式还成对象。代表函数unserialize()&#xff0c;将字符串还原成一个对象。 P…

MWC 2024丨Smart Health搭载高通Aware平台—美格发布智能健康看护解决方案,开启健康管理新体验

2月29日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;全球领先的无线通信模组及解决方案提供商——美格智能正式发布了新一代Cat.1模组SLM336Q&#xff0c;是中低速物联网应用场景的高性价比之选。本次还发布了首款搭载高通Aware™平台的智能看护解决方案MC303&#x…

[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

文章目录 一、tsconfig.json 的作用二、基本介绍三、Vue 3 的 tsconfig.json 的结构分析1. 总配置 tsconfig.json2. Web 侧 tsconfig.app.jsona. 继承基础配置b. 包含和排除的文件c. 编译器选项 3. 测试 tsconfig.vitest.jsona. 继承的基础配置b. 包含和排除的文件c. 编译器选项…

OD(13)之Mermaid饼图和象限图

OD(13)之Mermaid饼图和象限图使用详解 Author: Once Day Date: 2024年2月29日 漫漫长路才刚刚开始… 全系列文章可参考专栏: Mermaid使用指南_Once_day的博客-CSDN博客 参考文章: 关于 Mermaid | Mermaid 中文网 (nodejs.cn)Mermaid | Diagramming and charting tool‍‌⁡…

FPGA-学会使用vivado中的存储器资源RAM(IP核)

问题 信号源(例如ADC)以1us一个的速率产生12位的数据现要求获得连续1ms内的数据,通过串口以115200的波特率发到电脑。 分析 数据量是1000个 数据速率不匹配 数据内容未知 数据总数据量有限 数据的使用速度低于数据的产生速度 数据生产和消耗的位宽 数据量相对较…

ywtool check命令及ywtool clean命令

一.ywtool check命令 1.1 ywtool check -I 1.2 ywtool check all 1.3 ywtool check io 1.4 ywtool check elk 1.5 ywtool check php 1.6 ywtool check mysql 1.7 ywtool check nginx 1.8 ywtool check system 1.9 ywtool check docker_nbip [容器名称] 1.10 ywtool check 1.10…

综合练习(一)

目录 列出薪金高于部门 30 的所有员工薪金的员工姓名和薪金、部门名称、部门人数 列出与 ALLEN从事相同工作的所有员工及他们的部门名称、部门人数、领导姓名 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 列出薪金高于部门 30 的所…

基于JSON的Ollama和LangChain agent

到目前为止&#xff0c;我们都可能意识到&#xff0c;通过为LLMs提供额外的工具&#xff0c;我们可以显著增强它们的功能。 例如&#xff0c;即使是ChatGPT在付费版本中也可以直接使用Bing搜索和Python解释器。OpenAI更进一步&#xff0c;为工具使用提供了经过优化的LLM模型&am…