当前位置: 首页 > news >正文

网络通信——UDP协议。

短距离通信:交换机重要实现局域网内通信。

发送设备->交换机->路由器-》目标交换机-》目标主机-》目标进程

路由器:负责数据的路径选择,是信息的中转站,
在这里插入图片描述
路径选择:根据路由器路径规划的相关算法计算数据传输的对象,后到达接收方主机对应的路由器,该路由器将数据转发给接收方所在的交换机,最后将数据传到目标主机。在这里插入图片描述
在这里插入图片描述
上图表示每个路由器包含的路由表:存储从源网络到目标网络的最优路径信息,是路由器进行路径选择的核心依据。

IP地址:计算机的软件地址,用来标识计算机设备,同一局域网内不可能有相同IP地址的主机,
MAC地址:计算机的固定地址

在这里插入图片描述

网络的端口号:标记同一主机的不同网络进程。(针对不同软件的进程间通信)。
路由器路径规划算法:包含最短路径算法,最快路径算法。。。。

路由器路径规划算法主要用于为数据包选择从源到目的的最优传输路径,常见的主要有以下几类:

  1. 距离矢量算法:基于贝尔曼-福特算法,路由器通过与邻居交换“距离”(如跳数)和“方向”(下一跳)信息更新路由表,仅了解到达目标的距离和下一跳,不掌握全网拓扑。典型协议为RIP,适用于小型网络。

  2. 链路状态算法:路由器通过广播链路状态通告(LSA)获取全网拓扑,构建统一的链路状态数据库,再用迪杰斯特拉算法计算最短路径。典型协议如OSPF,适用于中大型网络,收敛快且无环路。

  3. 路径矢量算法:结合距离矢量和链路状态的特点,关注路径的完整信息(而非仅距离),可基于策略选择路径。典型协议为BGP,主要用于互联网中不同自治系统间的路由选择。

  4. 混合算法:融合多种算法的优势,例如EIGRP(增强内部网关路由协议),结合了距离矢量的简单性和链路状态的快速收敛特性,适用于企业级网络。

引申网络安全问题:针对数据转发后被截取截断的问题

网络协议:(网络通信标准)

OSI七层模型:开放系统互联模型。

不同设备间:网络通信的通信标准。

七层:
1.应用层:对象:数据信息
2.表示层:对象:数据安全性,操作:加密,解密处理,压缩解压缩处理
3.会话层:对象:数据传输的通道(一次会话)。
4.传输层:决定了数据传输的方式(UDP,TCP)
5.网络层:路由器的路径规划
6.数据链路层:!!!
7.物理层:物理设备标准,电器特性
在这里插入图片描述

TCP/IP模型:应用模型

五层:
1:应用层:应用层+表示层+会话层。
HTTP:超文本传输协议
HTTPS:(SSL加密算法)超文本传输协议
FTP:文件传输协议(TCP)
TFTP:简单文件传输协议(UDP)
MQTT:消息队列遥测传输协议(物联网协议),节省带宽。
DNS:域名解析服务(将一个域名转化成IP地址)
2.传输层:决定了数据传输的方式(UDP,TCP)
		TCP:传输控制协议(做路径规划)UDP:用户数据报协议(不做路径规划)
3.网络层:路由器的路径规划
		IP协议:IPV4IPV6
4.数据链路层:!!!
		ARP:地址解析协议
5.物理层:物理设备标准,电器特性
四层:

1:应用层:应用层+表示层+会话层。。
2.传输层:决定了数据传输的方式(UDP,TCP)
3.网络层:路由器的路径规划
4:数据链路层+物理层

4:IP协议

在这里插入图片描述

查看IP地n址:
win+r
在这里插入图片描述
ipconfig
在这里插入图片描述

在这里插入图片描述

区分网络位和主机位:

在这里插入图片描述
在这里插入图片描述
拿子网掩码来看:子网掩码为1的位置为网络位,子网掩码全为0的为主机位。网络位:192.168.0
主机位:140
在这里插入图片描述

特殊ip地址:

在这里插入图片描述

广播号和网关地址

在这里插入图片描述

五类IP地址:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

公私有IP:

在这里插入图片描述

公有ip的数据才能在广域网转发,私有ip只能在局域网内进行转发,本机私有ip被路由器转换成公有ip再通过局域网传输数据。

5:网络的端口号:

端口号:16位的整型数据(unsigned short)范围:(0–65535)
端口号功能:标记同一主机的不同网络进程

端口号分类:

在这里插入图片描述

数据包的封装和解封过程

在这里插入图片描述

6.ubuntu网络配置:

(1):ping命令:ping ip地址

在这里插入图片描述
查看当前主机与ip对应的服务器是否连通

(2):ifconfig

在linux查看当前主机ip地址。

(3):网络配置

在这里插入图片描述

7:网络协议——UDP

DP:传输层
用户数据报协议

(1)网络编程模型

	B/S模型:browser/server(浏览器/服务器)1:客户端是通用的客户端2:一般只做服务器的开发3:客户端加载的数据都来自服务器C/S模型:client/server(客户端对服务端模型)1:客户端是专用的客户端2:服务器和客户端都需要开发3:客户端可以保存资源进行本地加载,不需要数据都请求于服务器。

(2)UDP编程流程

在这里插入图片描述

UDP特点:

在这里插入图片描述

是一种机制简单,实时性高,但是不安全不可靠的协议。

1:面向数据包
2:无需建立连接
3:UDP:尽最大可能交付,一旦传输,在发送方传输完之前不会终止传输,可能存在发端发送速率快于收端接收速率,接收方缓冲区满了无法容纳传输过来的数据,导致丢包
4:一对一,一对多传输
5:机制简单,资源开销小,数据实时性高(VNC/直播)

如何避免丢包?

1:发送方降低发送效率,接收方提高接收效率

2:建立应答机制,设置单片数据编号。

一:socket函数

man socket查询socket函数相关信息:
在这里插入图片描述

二:sendto函数

在这里插入图片描述
man 7 ip:
在这里插入图片描述
struct sockaddr_in
在这里插入图片描述
网络字节序:大端
主机字节序:小端
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发送一段字符串给接收方: -

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/types.h>          /* See NOTES */
#include <arpa/inet.h>
#include <unistd.h>int main(int argc, const char *argv[])
{//socket():创建套接字//sendto():发送数据(UDP协议专用,需指定目标地址)//recvfrom():接收数据(UDP协议专用,可获取发送方地址)//close():关闭套接字/** socket()函数参数解析:* 第一个参数:AF_INET → 使用IPv4地址族* 第二个参数:SOCK_DGRAM → 套接字类型为数据报套接字(用于UDP协议)* 第三个参数:0 → 自动选择与套接字类型匹配的默认协议(此处为UDP协议)* 返回值:成功返回套接字文件描述符(非负整数),失败返回-1*/int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}//定义的接收方(服务端)的地址变量(IPv4专用地址结构)struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;                  //地址族:必须设置为AF_INET(IPv4)seraddr.sin_port = htons(50000);               //接收方的端口号:htons()将主机字节序转为网络字节序seraddr.sin_addr.s_addr = inet_addr("192.168.0.140");  //接收方IP地址:inet_addr()将点分十进制IP转为网络字节序整数/** sendto()函数参数解析:* 第一个参数:sockfd → 已创建的套接字文件描述符* 第二个参数:"hello world" → 待发送的数据缓冲区* 第三个参数:11 → 发送数据的长度(单位:字节,"hello world"共11个字符)* 第四个参数:0 → 发送标志,0表示默认方式(阻塞发送)* 第五个参数:(struct sockaddr *)&seraddr → 目标地址结构体指针(需强制转换为通用地址类型)* 第六个参数:sizeof(seraddr) → 目标地址结构体的长度(单位:字节)* 返回值:成功返回实际发送的字节数,失败返回-1*/ssize_t cnt = sendto(sockfd, "hello world", 11, 0, (struct sockaddr *)&seraddr, sizeof(seraddr));if (cnt < 0){perror("sendto error");return -1;}printf("cnt = %ld\n", cnt);  //打印实际发送的字节数//recvfrom:此处未实现接收逻辑,若需要接收服务端回复可添加此函数//close():关闭套接字,释放资源close(sockfd);return 0;
}

创建服务端用于接收发送数据

绑定当前主机的ip地址:ifconfig查询当前linux的ip地址
在这里插入图片描述

在这里插入图片描述

recvfrom函数会阻塞等待接收消息,和fgets相似。

src_addr和addrlen可以填NULL,只管接收就好了。

简易服务端代码

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/types.h>  /* See NOTES */
#include <arpa/inet.h>
#include <unistd.h>int main(int argc, const char *argv[])
{/** socket()函数:创建套接字* 参数1:AF_INET → 地址族,指定使用IPv4协议* 参数2:SOCK_DGRAM → 套接字类型,数据报套接字(用于UDP协议)* 参数3:0 → 协议选择,0表示根据前两个参数自动选择合适的协议(此处为UDP)* 返回值:成功返回套接字文件描述符(非负整数),失败返回-1*/int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}// 定义服务端地址结构体(用于绑定本地地址和端口)struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;                  // 地址族,必须与socket()的AF_INET一致seraddr.sin_port = htons(50000);               // 本地端口号,htons()将主机字节序转为网络字节序seraddr.sin_addr.s_addr = inet_addr("192.168.0.160");  // 本地IP地址,inet_addr()将点分十进制转为网络字节序/** bind()函数:将套接字与本地地址和端口绑定* 参数1:sockfd → 已创建的套接字文件描述符* 参数2:(struct sockaddr *)&seraddr → 通用地址结构体指针,需将sockaddr_in强制转换* 参数3:sizeof(seraddr) → 地址结构体的长度(字节数)* 返回值:成功返回0,失败返回-1*/int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (ret < 0){perror("bind error\n");return -1;};// 循环接收数据while (1){char buff[1024] = {0};  // 用于存储接收数据的缓冲区/** recvfrom()函数:接收UDP数据报(可获取发送方地址)* 参数1:sockfd → 绑定后的套接字文件描述符* 参数2:buff → 接收数据的缓冲区* 参数3:sizeof(buff) → 缓冲区的最大容量(字节数)* 参数4:0 → 接收标志,0表示默认方式(阻塞接收)* 参数5:NULL → 发送方地址结构体指针,此处为NULL表示不关心发送方地址* 参数6:NULL → 发送方地址结构体长度的指针,与参数5配合使用,此处为NULL* 返回值:成功返回实际接收的字节数,失败返回-1*/ssize_t cnt = recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL);if (cnt < 0){perror("recvfrom error");return -1;}// 打印接收的字节数和数据内容printf("cnt = %ld, buff = %s\n", cnt, buff);}// 关闭套接字(实际因while(1)循环不会执行到此处)close(sockfd);return 0;
}

在要打印接收到的消息来源信息时:1:针对客户端或接收端的地址结构体的结构, 2:针对网络字节序(大端),主机字节序(小端)的转换,3:为获取字符型ip地址而使用的类型转换函数。

应用实例:UDP的半双工聊天(轮流对话)

客户端代码:

#include <stdio.h>          // 标准输入输出函数,如printf、fgets等
#include <sys/socket.h>     // 提供socket相关函数定义
#include <netinet/in.h>     // 定义网络地址结构,如sockaddr_in
#include <netinet/ip.h>     // IP协议相关定义(包含netinet/in.h内容)
#include <sys/types.h>      // 基本系统数据类型定义
#include <arpa/inet.h>      // 提供IP地址转换函数,如inet_addr
#include <unistd.h>         // 提供close等系统调用
#include <string.h>         // 提供字符串操作函数,如memsetint main(int argc, const char *argv[])
{// UDP客户端主要流程:// 1. 创建socket// 2. 发送数据到服务器(sendto)// 3. 接收服务器的响应(recvfrom)// 4. 关闭socket(close)// 创建UDP socket// 参数说明:// AF_INET:使用IPv4协议// SOCK_DGRAM:使用UDP协议(无连接)// 0:自动选择对应协议(此处为IPPROTO_UDP)int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0)  // 检查socket创建是否成功{perror("socket error");  // 输出错误信息return -1;               // 失败返回-1}// 定义并初始化服务器(接收方)的地址信息struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;                // 使用IPv4地址族seraddr.sin_port = htons(50000);             // 服务器端口号(50000),htons转换字节序seraddr.sin_addr.s_addr = inet_addr("192.168.0.179");  // 服务器的IP地址char buff[1024] = {0};  // 用于存储发送和接收数据的缓冲区// 客户端主循环:持续发送数据并接收响应while (1){// 从标准输入(键盘)读取用户输入的内容fgets(buff, sizeof(buff), stdin);// 发送数据到服务器// 参数说明:// sockfd:socket描述符// buff:要发送的数据缓冲区// 0:此处原代码有误,实际应传入数据长度(如strlen(buff))// 0:标志位,使用默认行为// (struct sockaddr *)&seraddr:服务器地址结构// sizeof(seraddr):服务器地址结构的长度ssize_t cnt = sendto(sockfd, buff, 0, 0, (struct sockaddr *)&seraddr, sizeof(seraddr));if (cnt < 0)  // 检查发送是否失败{perror("sendto error");return -1;}// 清空缓冲区,准备接收服务器响应memset(buff, 0, sizeof(buff));// 接收服务器返回的数据// 参数说明:// sockfd:socket描述符// buff:接收数据的缓冲区// sizeof(buff):缓冲区大小// 0:标志位,使用默认行为// NULL, NULL:不需要获取发送方(服务器)地址信息,填NULLrecvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL);// 打印服务器发送的内容printf("ser-->cli : %s\n", buff);}// 关闭socket(实际因循环是死循环,这句代码不会执行到)close(sockfd);return 0;
}

服务端代码:

#include <stdio.h>          // 标准输入输出函数,如printf、perror等
#include <sys/socket.h>     //  socket相关函数定义,如socket、bind等
#include <netinet/in.h>     // 定义网络地址结构,如sockaddr_in
#include <netinet/ip.h>     // IP协议相关定义(包含netinet/in.h的内容)
#include <sys/types.h>      // 基本系统数据类型
#include <arpa/inet.h>      // 提供IP地址转换函数,如inet_addr、inet_ntoa等
#include <unistd.h>         // 提供close等系统调用
#include <string.h>         // 提供字符串操作函数,如memset、strlen等int main(int argc, const char *argv[])
{// UDP服务器主要流程:// 1. 创建socket// 2. 绑定地址和端口(bind)// 3. 循环接收数据(recvfrom)并发送响应(sendto)// 4. 关闭socket(close)// 创建UDP socket,参数说明:// AF_INET:使用IPv4协议// SOCK_DGRAM:使用UDP协议(无连接、不可靠)// 0:自动选择对应的协议(此处为IPPROTO_UDP)int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0)  // 检查socket创建是否成功{perror("socket error");  // 输出错误信息return -1;               // 失败返回-1}// 定义客户端地址结构,用于存储发送方(客户端)的地址信息struct sockaddr_in cliaddr;socklen_t clilen = sizeof(cliaddr);  // 客户端地址结构的长度// 定义并初始化服务器自己的地址信息struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;                // 使用IPv4地址族seraddr.sin_port = htons(50000);             // 设置端口号(50000),htons将主机字节序转为网络字节序seraddr.sin_addr.s_addr = inet_addr("192.168.0.179");  // 设置绑定的IP地址,inet_addr将字符串IP转为网络字节序// 将socket与服务器地址绑定// 参数:socket描述符、服务器地址结构(需强制转换类型)、地址结构长度int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (ret < 0)  // 检查绑定是否成功{perror("bind error");  // 输出错误信息return -1;             // 失败返回-1}char buff[1024] = {0};  // 用于存储接收和发送的数据缓冲区// 服务器主循环,持续接收客户端数据并回复while (1){memset(buff, 0, sizeof(buff));  // 清空缓冲区// 接收客户端发送的数据// 参数:socket描述符、接收缓冲区、缓冲区大小、标志(0为默认)、//       客户端地址结构(用于存储发送方信息)、地址结构长度的指针ssize_t cnt = recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&cliaddr, &clilen);if (cnt < 0)  // 检查接收是否失败{perror("recvfrom error");return -1;}else if (0 == cnt)  // 接收字节数为0,通常表示连接关闭(UDP中较少见){printf("cnt = %ld\n", cnt);break;  // 退出循环}// 打印接收到的信息:客户端IP、端口、数据长度、数据内容printf("[%s : %d][%ld] %s\n", inet_ntoa(cliaddr.sin_addr),  // 将网络字节序IP转为字符串ntohs(cliaddr.sin_port),      // 将网络字节序端口转为主机字节序cnt,                          // 接收的字节数buff);                        // 接收的数据内容// 从标准输入获取要回复的内容fgets(buff, sizeof(buff), stdin);// 发送数据给客户端// 参数:socket描述符、发送缓冲区、数据长度、标志(0为默认)、//       目标客户端地址结构、地址结构长度sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr *)&cliaddr, clilen);}close(sockfd);  // 关闭socket,释放资源return 0;
}

作业1:实现全双工聊天

在这里插入图片描述

头文件部分:

#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <pthread.h>#endif

客户端代码:


#include"head.h"#define SER_PORT 50000
#define SER_IP   "192.168.0.179"struct sockaddr_in seraddr;int init_udp_cli()
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SER_PORT);seraddr.sin_addr.s_addr = inet_addr(SER_IP);return sockfd;
}void *send_msg(void *arg)
{char buff[1024] = {0};int sockfd = *((int *)arg);while (1){fgets(buff, sizeof(buff), stdin);ssize_t cnt = sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));if (cnt < 0){perror("sendto error");break;}}return NULL;
}void *recv_msg(void *arg)
{char buff[1024] = {0};int sockfd = *((int *)arg);while (1){memset(buff, 0, sizeof(buff));ssize_t cnt = recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL);if (cnt < 0){perror("recvfrom error");break;}printf("B-->A : %s\n", buff);}return NULL;
}int main(int argc, const char *argv[])
{pthread_t tid[2];int sockfd = init_udp_cli();if (sockfd < 0){return -1;}sendto(sockfd, "hello", 5, 0, (struct sockaddr *)&seraddr, sizeof(seraddr));pthread_create(&tid[0], NULL, send_msg, &sockfd);pthread_create(&tid[1], NULL, recv_msg, &sockfd);pthread_join(tid[0], NULL);pthread_join(tid[1], NULL);close(sockfd);return 0;
}

服务端代码:

#define SER_PORT 50000
#define SER_IP "192.168.0.179"struct sockaddr_in cliaddr;
socklen_t clilen;int init_udp_ser()
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SER_PORT);seraddr.sin_addr.s_addr = inet_addr(SER_IP);int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (ret < 0){perror("bind error");return -1;}return sockfd;
}void *send_msg(void *arg)
{char buff[1024] = {0};int sockfd = *((int *)arg);while (1){fgets(buff, sizeof(buff), stdin);size_t cnt = sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr *)&cliaddr, clilen);if (cnt < 0){perror("sendto error");break;}}return NULL;
}void *recv_msg(void *arg)
{char buff[1024] = {0};int sockfd = *((int *)arg);while (1){ssize_t cnt = recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL);if (cnt < 0){perror("recvfrom error");break;}printf("A--->B: %s\n", buff);}return NULL;
}int main(int argc, const char *argv[])
{pthread_t tid[2];char buff[1024] = {0};clilen = sizeof(cliaddr);int sockfd = init_udp_ser();if (sockfd < 0){return -1;}recvfrom(sockfd, buff, sizeof(buff), 0, (struct sockaddr *)&cliaddr, &clilen);pthread_create(&tid[0], NULL, send_msg, &sockfd);pthread_create(&tid[1], NULL, recv_msg, &sockfd);pthread_join(tid[0], NULL);pthread_join(tid[1], NULL);return 0;
}

作业2:使用UDP实现文件的传输(图片)

头文件:

#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <pthread.h>#endif

客户端代码:

#include "head.h"#define SER_PORT 50000
#define SER_IP   "192.168.0.179"struct sockaddr_in seraddr;int init_udp_cli()
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SER_PORT);seraddr.sin_addr.s_addr = inet_addr(SER_IP);return sockfd;
}int send_file(int sockfd, const char *filename)
{char buff[1024] = {9};int fd = open(filename, O_RDONLY);if (fd < 0){perror("open file error");return -1;}off_t len = lseek(fd, 0, SEEK_END);lseek(fd, 0, SEEK_SET);printf("len = %ld\n", len);sendto(sockfd, &len, sizeof(len), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));while (1){size_t cnt = read(fd, buff, sizeof(buff));if (cnt <= 0){break;}sendto(sockfd, buff, cnt, 0, (struct sockaddr *)&seraddr, sizeof(seraddr));usleep(1);}return 0;
}int main(int argc, const char *argv[])
{if (argc < 2){printf("Usage : ./a.out <sendfile>\n");return -1;}pthread_t tid[2];int sockfd = init_udp_cli();if (sockfd < 0){return -1;}send_file(sockfd, argv[1]);close(sockfd);return 0;
}

服务端(接收端)代码:

#include "head.h"#define SER_PORT 50000
#define SER_IP "192.168.0.179"int init_udp_ser()
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){perror("socket error");return -1;}struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(SER_PORT);seraddr.sin_addr.s_addr = inet_addr(SER_IP);int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (ret < 0){perror("bind error");return -1;}return sockfd;
}int recv_file(int sockfd, const char *filename)
{char buff[1024] = {0};int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);if (fd < 0){perror("open file error");return -1;}off_t len = 0;recvfrom(sockfd, &len, sizeof(len), 0, NULL, NULL);printf("len = %ld\n", len);while (1){ssize_t cnt = recvfrom(sockfd, buff, sizeof(buff), 0, NULL, NULL);write(fd, buff, cnt);len -= cnt;if (0 == len){break;}}return 0;
}int main(int argc, const char *argv[])
{if (argc < 2){printf("Usage : ./a.out <recvfile>\n");return -1;}int sockfd = init_udp_ser();if (sockfd < 0){return -1;}recv_file(sockfd, argv[1]);close(sockfd);return 0;
}

抓包:

wireshark
网络抓包:抓取通过设备网卡的网络数据,从而调试和分析程序。
1.使用wireshark
sudo wireshark
2:选取要抓取的网卡
3:选择过滤条件
4:开始抓取
5:进行网络通信

UDP报文头部:

在这里插入图片描述
UDP头部:总共8字节
源端口号:发送方网络进程端口号
目标端口号:接收方网络进程端口号
长度:UDP发送的报文的整体长度(UDP头部+UDP正文)
数据差错校验。
在这里插入图片描述

在这里插入图片描述

http://www.dtcms.com/a/346341.html

相关文章:

  • Kubernetes 1.28 集群部署指南(基于 Containerd 容器运行时)
  • 笔记:二叉树构建方法
  • 从“配置化思维”到“前端效率革命”:xiangjsoncraft 如何用 JSON 简化页面开发?
  • 【源码】MES系统:从下达计划、执行反馈、异常预警到过程控制的一整套执行中枢。
  • FastTracker:实时准确的视觉跟踪
  • 一键部署openGauss6.0.2轻量版单节点
  • DPY-3010: connections to this database server version are not supported by p
  • LoRA内幕机制解析(53)
  • Design Compiler:层次模型(Block Abstraction)的简介
  • 什么是神鸟云?
  • 亚马逊老品怎么再次爆发流量?
  • 软件测试要怎么自学?
  • CVPR 2025 | 哈工大港大DeCLIP:解耦CLIP注意力实现开放词汇感知!
  • RK3588随笔:MIPI协议——D-PHY 物理层的自定义和校验
  • codeforces round 1043(div3) 补题
  • Finite State Machine(FSM) for the Development Mode
  • NVM-Windows 命令大全
  • YOLO --- YOLOv5模型以及项目详解
  • Tiger任务管理系统-13
  • MiniOB环境部署开发(使用Docker)
  • FPC设计技巧
  • 解释实现哈希值作为唯一的ID以及后面的hexdigest是什么意思
  • 剑指数组相关
  • CSS自定义属性(CSS变量)
  • 全面解析 `strncasecmp` 字符串比较函数
  • ES6变量与解构:let、const与模板字符串全解析
  • 53 C++ 现代C++编程艺术2-枚举和枚举类
  • 大麦盒子DM4036亲测刷包实践笔记
  • AI领域的语义空间是什么?
  • 波士顿房价线性回归预测讲解