千锋教育+计算机四级网络-计算机网络学习-04
UDP概述
UDP协议
面向无连接的用户数据报协议,在传输数据前不需要先建立连接;目地主机的运输层收到UDP报文后,不需要给出任何确认
UDP特点
- 相比TCP速度稍快些
- 简单的请求/应答应用程序可以使用UDP
- 对于海量数据传输不应该使用UDP
- 广播和多播应用必须使用UDP
UDP应用
DNS(域名解析)、NFS(网络文件系统)、RTP(流媒体)等
网络编程接口socket
网络通信要解决的是不同主机进程间的通信
- 不同主机识别,哪一个主机发,哪一个主机收
- 以及多重协议的识别问题,是UDP还是TCP
- 首要问题是网络间进程标识问题,因为一个主机存在很多进程,你需要准确的把数据给目的进程(使用端口表示一个进程),哪一个端口发,哪一个端口收
总结就是:IP、端口、协议
20世纪80年代初,加州大学Berkeley分校在BSD(一个UNIX OS版本)系统内实现了TCP/IP协议;其网络程序编程开发接口为socket
随着UNIX以及类UNIX操作系统的广泛应用, socket成为最流行的网络程序开发接口
socket作用
提供不同主机上的进程之间的通信
socket特点
- socket也称“套接字”
- 是一种文件描述符(特殊的文件描述符),代表了一个通信管道的一个端点(因此socket其实创建的就是一个虚拟的管道-全双工,可以这么简单的理解)
- 类似对文件的操作一样,可以使用read、write、close等函数对socket套接字进行网络数据的收取和发送等操作
- 得到socket套接字(描述符)的方法调用socket()
UDP编程C/S架构
这个架构决定我们写代码的流程

UDP编程-创建套接字
创建socket套接字
int socket(int family,int type,int protocol);
功能:
创建一个用于网络通信的socket套接字(描述符)
参数:
family:协议族(AF_INET、AF_INET6、PF_PACKET等)
type:套接字类(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)
protocol:协议类别(0、IPPROTO_TCP、IPPROTO_UDP等
protocol写0(自动寻找),让它以type为主,确定协议SOCK_STREAM--TCP
SOCK_DGRAM--UDP
返回值:
套接字
特点:
创建套接字时,系统不会分配端口
创建的套接字默认属性是主动的,即主动发起服务的请求;当作为服务器时,往往需要修改为被动的
头文件:
#include <sys/socket.h>
创建UDP套接字demo
int sockfd = 0;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd < 0)
{perror("socket");close(sockfd);exit(-1);
}注意:
AF_INET:IPv4协议
SOCK_DGRAM:数据报套接字
0:选择所给定的family和type组合的系统默认值
IPv4套接字地址结构
struct sockaddr_in{sa_family_t sin_family;//2字节 -- 协议族in_port_t sin_port;//2字节 --端口struct in_addr sin_addr;//4字节 --发送方地址或接收方地址char sin_zero[8]//8字节 ---为0,起补位作用,因为要求结构体16个字节,因此定义了8字节的补位};struct in_addr //该结构体只有一个成员,属于历史遗留问题,之前是有其他成员的{in_addr_t s_addr;//4字节}
在赋值结构体的时候,由于 sin_zero的值需要赋值0,那么我们可以一开始就把结构体清零,然后只赋值协议、端口、IP地址即可
当主机是IPV4或者IPV6发送数据的时候,由于IP地址不同,导致函数使用的不同,因此为了让函数的实用性更强,那么我就把IPV4和IPV6当成整体,因此就把结构体转换为相同的类型即可
为了使不同格式地址能被传入套接字函数,地址须要强制转换成通用套接字地址结构
头文件:#include <netinet/in.h>
struct sockaddr
{
sa_family_t sa_family; // 2字节
char sa_data[14] //14字节
};

为了类型转换,就像一个函数能处理char*、int*,那么这个函数就需要成为void*,数据转换,其实我们自己设计一个通用函数的时候也需要注意,如果类型不同,那么我们需要存在一个通用的类型,像void*,能被任何一个数据类型赋值,因此同理,这里也产生了一个类似于void*的类型(为了数据转换,以便处理更多的数据类型)
两种地址结构使用场合
在定义源地址和目的地址结构的时候,选用struct sockaddr_in;
例:
struct sockaddr_in my_addr;
这个特点记住就好,等写代码的时候注意一下
当调用编程接口函数,且该函数需要传入地址结构时需要用struct sockaddr进行强制转换
例:
bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr));
发送数据—sendto函数
ssize_t sendto(int sockfd,const void *buf,
size_t nbytes,int flags,
const struct sockaddr *to,
socklen_t addrlen);
功能:
向to结构体指针中指定的ip,发送UDP数据
参数:
sockfd:套接字
buf: 发送数据缓冲区
nbytes: 发送数据缓冲区的大小
flags:一般为0
to: 指向目的主机地址结构体的指针
addrlen:to所指向内容的长度
注意:
通过to和addrlen确定目的地址
可以发送0长度的UDP数据包
返回值:
成功:实际发送数据的字符数
失败: -1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main(int argc,char *argv[])
{//定义好端口和IP地址,并且IP地址是字符串形式,其实这里可以不用初始化unsigned short server_port= 808; //可以赋值0char *server_ip = "192.168.52.1"; //可以赋值NULL//传递参数需要符合规定,否则错误,并且退出if(argc < 3 ){printf("error\n");exit(1);}//把从终端传进去的IP地址和端口号进行赋值server_ip = argv[1];//通过main函数传参,传入端口号server_port= atoi(argv[2]); //由于终端输入的是字符串,而端口号是整型,因此使用atoi函数把数字字符串转换为数字/*创建UDP套接字*/int sockfd;sockfd = socket(AF_INET,SOCK_DGRAM,0); //IPV4和UDPif(sockfd < 0){perror("socket");exit(-1);}/*填充目的server socket地址*/struct sockaddr_in dest_addr;bzero(&dest_addr,sizeof(dest_addr)); //先清零dest_addr.sin_family = AF_INET;//目的套接字地址的协议家族赋值dest_addr.sin_port = htons(server_port);//目的套接字地址的端口号赋值,并且转成网络字节序inet_pton(AF_INET,server_ip,&dest_addr.sin_addr);//目的套接字地址的ip地址赋值printf("send data to UDP server %s:%d!\n",server_ip,port);/*发送数据到目的server*/while(1){char send_buf[512];fgets(send_buf,sizeof(send_buf),stdin); //使用fgets从终端中输入字符串send_buf[strlen(send_buf)-1] = '\0';//字符串最后一个'\n'变成'\0' //这个很容易忘记,在末尾添加结束字符sendto(sockfd,send_buf,strlen(send_buf),0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));}close(sockfd); //记得使用完成后,关闭套接字return 0;
}
绑定 bind函数
UDP网络程序想要收取数据需什么条件?
确定的ip地址
确定的port
怎样完成上面的条件呢?
接收端 使用bind函数,来完成地址结构与socket套接字的绑定,这样ip、port就固定了
发送端 在sendto函数中指定接收端的ip、port,就可以发送数据了
因此bind既可以使用在发送端,也可以使用在接收端(客户端和服务端都可以使用bind,都是一般服务端使用bind)
int bind(int sockfd,
const struct sockaddr *myaddr,socklen_t addrlen);
功能:
将本地协议地址与sockfd绑定
参数:
sockfd: socket套接字
myaddr: 指向特定协议的地址结构指针
addrlen:该地址结构的长度
返回值:
成功:返回0
失败:其他

struct sockaddr_in Mysource_addr;bzero(&Mysource_addr,sizeof(Mysource_addr));Mysource_addr.sin_family = AF_INET;//目的套接字地址的协议家族赋值Mysource_addr.sin_port = htons(8000);//目的套接字地址的端口号赋值Mysource_addr.sin_addr.s_addr = htonl(INADDR_ANY);INADDR_ANY是通配地址,值为0
接收数据—recvfrom 函数
ssize_t recvfrom(int sockfd, void *buf,
size_t nbytes,int flags,
struct sockaddr *from,
socklen_t *addrlen);
功能:
接收UDP数据,并将源地址信息保存在from指向的结构中
并且recvfrom默认是带阻塞的,他需要等信息
参数:
sockfd: 套接字
buf:接收数据缓冲区
nbytes:接收数据缓冲区的大小
flags: 套接字标志(常为0)
from: 源地址结构体指针,用来保存数据的来源
addrlen: from所指内容的长度
注意:
通过from和addrlen参数存放数据来源信息
from和addrlen可以为NULL, 表示不保存数据来源
返回值:
成功:接收到的字符数
失败: -1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main(int argc,char *argv[])
{struct sockaddr_in Mysource_addr;bzero(&Mysource_addr,sizeof(Mysource_addr));Mysource_addr.sin_family = AF_INET;//目的套接字地址的协议家族赋值Mysource_addr.sin_port = htons(8000);//目的套接字地址的端口号赋值Mysource_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*创建UDP套接字*/int sockfd;sockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd < 0){perror("socket");exit(-1);}if(bind(sockfd,(struct sockaddr *)&Mysource_addr,sizeof(Mysource_addr)) != 0 ){perror("bind is error");exit(1);}char recvBuff[512];while(1){while( recvfrom(sockfd,recvBuff,512,0,NULL,NULL) == 0 );printf("%s\n",recvBuff);}
}

模拟QQ情况
QQ既可以发信息也可以收消息,说明存在多进程或者多线程情况,一个进程或者线程收消息,而另外一个发消息

独立完成改代码
相关文章:
千锋教育+计算机四级网络-计算机网络学习-04
UDP概述 UDP协议 面向无连接的用户数据报协议,在传输数据前不需要先建立连接;目地主机的运输层收到UDP报文后,不需要给出任何确认 UDP特点 相比TCP速度稍快些简单的请求/应答应用程序可以使用UDP对于海量数据传输不应该使用UDP广播和多播应用…...
蓝桥杯算法训练合集十四 1.P08052.P07053.同余方程4.P08015.ascii应用
目录 1.P0805 2.P0705 3.同余方程 4.P0801 5.ascii应用 1.P0805 问题描述 当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数&…...
判断字符串中的字符的类型isdecimal();isalpha();isdigit();isalnum()
【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串中的字符的类型 isdecimal();isalpha();isdigit();isalnum() [太阳]选择题 对于代码中isdecimal()和isalnum()输出的结果是? s "ABc123&…...
VSCode远程调试Linux代码,python解释器配置
安装插件并配置 安装后找到插件图标,点击 点击SSH上的 号 在弹出框中输入命令:ssh usernameip -p port username: 远程服务器的用户名 ip: 远程ip port:端口号,没有可以不用 输入完毕后点击enter 选择ssh配置文件保存…...
03:入门篇 - CTK Plugin Framework 基本原理
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 CTK Plugin Framework 技术是面向 C++ 的动态模型系统。该系统允许插件之间的松散耦合,并且提供了设计良好的方式来进行功能和数据的交互。此外,它没有预先对插件施加限制,这样就可以很容易地将插件的相关…...
面试攻略,Java 基础面试 100 问(九)
数组有没有 length()方法?String 有没有 length()方法? 数组没有 length()方法,有 length 的属性。String 有 length()方法。JavaScript 中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java混淆。 在 Java 中&…...
JavaScript 代码不嵌套主义
文章目录前言一、何为嵌套代码二、避免嵌套1.提炼抽取2.反转排列总结前言 看过不少过度嵌套的代码, 我真正意识到问题的严重性是刚入职那会, 我在一个老项目里看到了40个连续的else if, 套了6层的if, for和forEach, 因为我们并没有做什么限制代码嵌套的提前约定. 呃, 那之后认…...
使用默认参数的4大要点
概述 默认参数是C中新增的特性。在C中,可以为函数的参数指定默认值。调用函数时,如果没有指定实参,则自动使用默认参数。默认参数的基本语法这里就不作介绍了,下面重点介绍使用默认参数的一些知识要点。 基本规则 1、当函数中某个…...
Linux文件系统中的硬链接及常见面试题
如果能对inode的概念有所了解,对理解本文会有所帮助。如果对inode的概念不太清楚也没有关系,我们会捎带介绍一下。在文件系统的实现层面,我们可以认为包含两个组件:一个是包含数据块的池子,池子中的数据块是等大小的&a…...
opencv-StereoBM算法
原理解释目前立体匹配算法是计算机视觉中的一个难点和热点,算法很多,但是一般的步骤是:A、匹配代价计算匹配代价计算是整个立体匹配算法的基础,实际是对不同视差下进行灰度相似性测量。常见的方法有灰度差的平方SD(squ…...
图像分类竞赛进阶技能:OpenAI-CLIP使用范例
OpenAI-CLIP 官方介绍 尽管深度学习已经彻底改变了计算机视觉,但目前的方法存在几个主要问题:典型的视觉数据集是劳动密集型的,创建成本高,同时只教授一组狭窄的视觉概念;标准视觉模型擅长于一项任务且仅擅长于一项任务,并且需要大…...
Metasploit框架基础(一)
文章目录前言一、基础认知二、批量POC/EXP的构想三、poc检测框架的简单实现四、xray五、Meatsploit框架参考前言 Metasploit 一款渗透测试框架漏洞利用的集合与构建和定制满足你的需求的基础漏洞利用和验证的工具 这几个说法都是百度或者官方文档中出现的手法,说…...
pytorch零基础实现语义分割项目(二)——标签转换与数据加载
数据转换与加载项目列表前言标签转换RGB标签到类别标签映射RGB标签转换成类别标签数据数据加载随机裁剪数据加载项目列表 语义分割项目(一)——数据概况及预处理 语义分割项目(二)——标签转换与数据加载 语义分割项目&#x…...
python(8.5)--列表习题
目录 一、求输出结果题 二、计算列表元素个数 三、查找是否存在某元素 四、删除某元素 五、如何在列表中插入元素 六、如何从列表中删除重复的元素 七、 如何将列表中的元素按照从小到大的顺序排序 八、从列表中删除重复的元素 九、大到小的顺序排序 一、求输出结…...
rt-thread pwm 多通道
一通道pwm参考 https://blog.csdn.net/yangshengwei230612/article/details/128738351?spm1001.2014.3001.5501 以下主要是多通道与一通道的区别 芯片 stm32f407rgt6 1、配置PWM设备驱动相关宏定义 添加PWM宏定义 #define BSP_USING_PWM8 #define BSP_USING_PWM8_CH1 #d…...
C语言练习 | 初学者经典练习汇总
目录 1、下面代码输出多少,为什么? 2、你要好好学习么? 3、一直写代码, 4、两个数求最大值 5、输入1-5输出工作日,输入6-7输出休息日,其他输入错误 6、写一个输入密码的代码 7、怎么样当输入数字时候…...
华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 卡片组成的最大数字(Python) | 机试题算法思路 华为OD机试 - 网上商城优惠活动(一)(Python) | 机试题算法思路 华为OD机试 - 统计匹配的二元组个数(Python) | 机试题算法思路 华为OD机试 - 找到它(Python) | 机试题算法思路 华为OD机试…...
「6」线性代数(期末复习)
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 第五章 相似矩阵及二次型 &2)方阵的特征值与特征向量 &3ÿ…...
1.1 硬件与micropython固件烧录及自编译固件
1.ESP32硬件和固件 淘宝搜ESP32模块,20-50元都有,自带usb口,即插即用. 固件下载地址:MicroPython - Python for microcontrollers 2.烧录方法 为简化入门难度,建议此处先使用带GUI的开发工具THonny,记得不是给你理发的tony老师. 烧录的入口是: 后期通过脚本一次型生成和烧…...
【MySQL进阶】视图 存储过程 触发器
😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...



