前言

说明:

  • demo 基于 Linux。

5. UDP 网络编程

UDP 是无连接的,不需要建立连接。

5.1 UDP 的工作原理

参考图:

主机B的数据包中包含目的主机的IP+端口号。

其中IP是把数据的目的主机地址,端口号是目的主机对用的程序。

路由器小知识

  • IP:主机地址。如目的IP,每个路由器都会检查IP,若在本地,就往本地端口转发,若不在,就往外端口发。(在转发过程中是不会变的)
  • MAC:设备地址。目的MAC,下一个物理连接的设备地址。(在转发过程中可能会变,因为参考的是下一个,而不是最终目的)

5.2 UDP 的高效性

UDP 不需要建立连接和响应校验,实时性比 TCP 高。

一般用在网络实时传递的视频或者音频中,因为丢失部分数据也不会影响太大。

5.3 实现 UDP 服务端/客户端

5.3.1 概念

UDP 服务器和客户端均只需一个套接字:

  • TCP 中,套接字之间应该是一对一的关系。
  • UDP 中,不管是服务器端还是客户端都只需要 1 个套接字,就可以任意传输。

如图:

5.3.2 UDP 的数据 I/O 函数

/*
sock: 用于传输数据的 UDP 套接字
buff: 保存待传输数据的缓冲地址值
nbytes: 待传输的数据长度,以字节为单位
flags: 可选项参数,若没有则传递 0
to: 存有目标地址的 sockaddr 结构体变量的地址值
addrlen: 传递给参数 to 的地址值结构体变量长度
成功时返回传输的字节数,失败时返回 -1
*/
#include <sys/socket.h>
ssize_t sendto(int sock, void *buff, size_t nbytes, int flags,
struct sockaddr *to, socklen_t addrlen); /*
sock: 用于传输数据的 UDP 套接字
buff: 保存待传输数据的缓冲地址值
nbytes: 待传输的数据长度,以字节为单位
flags: 可选项参数,若没有则传递 0
from: 存有发送端地址信息的 sockaddr 结构体变量的地址值
addrlen: 保存参数 from 的结构体变量长度的变量地址值。
成功时返回传输的字节数,失败时返回 -1
*/
#include <sys/socket.h>
ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags,
struct sockaddr *from, socklen_t *addrlen);

5.3.3 UDP 客户端地址分配

TCP 中客户端地址可以设置也可以系统分配,(TCP connect() 函数自动完成分配IP&端口号),建立连接后就固定使用。

UDP 中客户端中调用 sendto() 函数时自动分配 IP 和 端口号,首次调用才分配,分配后使用直至程序结束(有兴趣可以看看UDP打洞技术)。

也可以在调用 sendto() 函数前使用 bind() 函数绑定本机 IP。

5.4 UDP 的数据传输特性

TCP 是流式的数据传输,消息没有边界,需要应用层自己去定义消息边界。

UDP 是数据报传输,所以协议保证了一次只能接收一个数据报。

个人表达:数据边界意思是,数据会不会自动分割,比如两个结构体连续存在一段内存中,那是有边界的,结构体把其分割了。若把其数据拷贝到数组里面,那是无边界的,因为分不清从哪里才是分割线

所以UDP中本端发 N 次到对端,对端就得收 N 次。

5.5 UDP 调用 connect 函数

UDP套接字分

  • 未连接(unconnected)UDP 套接字。
  • 已连接(connect)UDP 套接字。

了解下 sendto() 函数传输数据过程

  1. 第 1 阶段:向 UDP 套接字注册目标 IP 和端口号。
  2. 第 2 阶段:传输数据。
  3. 第 3 阶段:删除 UDP 套接字中注册的目标地址信息。

其实需要频繁发送,那第一阶段和第三阶段是重复多余的,所以可以使用 已连接(connect)UDP 套接字。

创建已连接 UDP 套接字

  • 注意:这里的已连接并不是与对端建立连接,而是绑定目标端口到 UDP socket 中,后面调用 sendto() 就不用执行①、③步了。
sock = socket(PF_INET, SOCK_DGRAM, 0);
memset(&adr, 0, sizeof(adr));
adr.sin_family = AF_INET;
adr.sin_addr.s_addr = inet_addr(argv[1]);
adr.sin_port = htons(atoi(argv[2]));
connect(sock, (struct sockaddr *)&adr, sizeof(adr));

小知识

  • UDP 是可以使用 bind() 函数的,主要是配置本地IP和端口号。若不适用,则由系统随机分配。
  • UDP 是可以使用 connect() 函数的,主要是配置远端IP和端口号。若不使用,则每次调用 sendto() 函数时都要设置、删除远端IP和端口号,耗时。

参考

【网络编程】TCPIP-5-UDP的更多相关文章

  1. 网游中的网络编程3:在UDP上建立虚拟连接

    目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...

  2. 网络编程第三讲UDP编写

    网络编程第三讲UDP编写 一丶UDP简介 UDP是面向无连接的.就是说数据传输会丢掉.网络延时比较大的情况下.会早上丢包.例如视频通话.就是UDP UDP不需要建立建立. 下面有UDP编写流程图 下图 ...

  3. Socket网络编程TCP、UDP演示样例

    Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...

  4. C#网络编程入门之UDP

    目录: C#网络编程入门系列包括三篇文章: (一)C#网络编程入门之UDP (二)C#网络编程入门之TCP (三)C#网络编程入门之HTTP 一.概述 UDP和TCP是网络通讯常用的两个传输协议,C# ...

  5. Linux Linux程序练习十一(网络编程大文件发送UDP版)

    //网络编程发送端--大文件传输(UDP) #include <stdio.h> #include <stdlib.h> #include <string.h> # ...

  6. Linux网络编程10——使用UDP实现五子棋对战

    思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...

  7. javase的网络编程(InetAddress,UDP,TCP,URL,Socket,DatagramSocket)

    通过一段时间对java网络编程相关内容的学习,写下这篇随笔,对这一部分的知识进行梳理和总结. 网络编程 一.网络编程三要素: IP地址:网络会给每个联网的主机分配一个数字的编码地址,该地址就是IP地址 ...

  8. TCP/IP网络编程之基于UDP的服务端/客户端

    理解UDP 在之前学习TCP的过程中,我们还了解了TCP/IP协议栈.在四层TCP/IP模型中,传输层分为TCP和UDP这两种.数据交换过程可以分为通过TCP套接字完成的TCP方式和通过UDP套接字完 ...

  9. 网络编程原理与UDP实现

    如何发送数据包? Q:当应用程序产生数据的时候,需要去构造数据包并发送到网络上去,但是由谁负责处理呢? A:现代操作系统负责数据包得构造与发送,应用程序只需提供数据. 当应用程序产生数据时,应用程序将 ...

  10. Linux 网络编程五(UDP协议)

    UDP和TCP的对比 --UDP处理的细节比TCP少. --UDP不能保证消息被传送到目的地. --UDP不能保证数据包的传递顺序. --TCP处理UDP不处理的细节. --TCP是面向连接的协议 - ...

随机推荐

  1. PE文件头格式解析

    前言: 昨天写了一题de1ctf的题,发现要脱壳,手脱之后发现要iat修复,我就发现自己在这块知识缺失了,win逆向,好像一直都是打ctf,然后用逆向方法论去肝的 其他方面倒是没有很深入学习,但实际上 ...

  2. Linux 3.16 release 贡献度

    内核 3.16 release 的贡献度可以在下面网页看到: http://www.remword.com/kps_result/3.16_whole.html 一共发布了 12802 个补丁, 18 ...

  3. .Net5 IdentityServer4下SqlServer和Mysql数据迁移

    1.概念 以下概念从官网整理的,我也是看官网一步一步学习的 官网地址 https://identityserver4.readthedocs.io/en/latest/index.html 1.1 I ...

  4. makedown语法小记

    1.标题,支持六级 # 这是一级标题 ## 这是二级标题 ### 这是三级标题 2.斜体 *这是斜体* 3.加粗 **这是加粗** 4.斜体加粗 ***这是斜体加粗*** 5.删除线 ~~这是删除线~ ...

  5. 『与善仁』Appium基础 — 4、常用ADB命令(一)

    目录 1.启动和关闭ADB服务 2.查看ADB版本 3.指定adb server的网络端口 4.查询已连接设备/模拟器 5.获取安卓系统版本 6.为命令指定目标设备 7.发送文件到手机 8.从手机拉取 ...

  6. [005] - JavaSE面试题(五):String类

    第一期:Java面试 - 100题,梳理各大网站优秀面试题.大家可以跟着我一起来刷刷Java理论知识 [005] - JavaSE面试题(五):String类 第1问:String.StringBuf ...

  7. Java基础之反射生成JDK动态代理

    在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口.通过这个类和接口可以生成JDK动态代理类或动态代理对象. JDK动态代理例子: / ...

  8. .net core工具组件系列之Redis—— 第一篇:Windows环境配置Redis(5.x以上版本)以及部署为Windows服务

    Cygwin工具编译Redis Redis6.x版本是未编译版本(官方很调皮,所以没办法,咱只好帮他们编译一下了),所以咱们先下载一个Cygwin,用它来对Redis进行编译. Cygwin下载地址: ...

  9. xampp中修改mysql默认空密码

    打卡记录: 1. mysql用户的相关信息是保存在mysql数据库的user表中的,并且该表的密码字段(Password)是通过PASSWORD方法加密存储的,所以不能直接修改成123456. 2. ...

  10. chcod炸弹

    [题目描述] 话说Cpp国和Pas国发生了战争, Pas国派出了强大的飞机战队, Cpp国于是使出了炸弹CHCOD 来反击Pas国的飞机舰队.然而CHCOD的发射器,只能逐渐往上打.所以Cpp国现在只 ...