网络编程(三)UDP TFTP协议

文章目录

  • 一、 UDP
    • (一)概述
    • (二)流程
  • 二、收发函数
    • (一)recvfrom
    • (二)sendto
  • 三、实现一个简单的udp服务端和客户端
  • 四、实现tftp客户端协议

一、 UDP

(一)概述

UDP(User Datagram Protocol)用户数据报协议:
是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

  • 注:
    默认支持并发
    不存在“粘包”的现象

(二)流程

在这里插入图片描述
服务器流程
创建套接字–socket()
填充服务器网络信息结构体
将套接字与服务器网络信息结构体绑定–bind()
收发数据–sendto() recvfrom()
关闭套接字–close()

客户端流程
创建套接字–socket()
填充服务器网络信息结构体
收发数据–sendto() recvfrom()
关闭套接字–close()

二、收发函数

(一)recvfrom

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
功能:在套接字上接收一条消息
参数:前 4 个参数用法和 recv 函数的4个参数用法一模一样后 2 个参数用法和 accept 函数的后两个参数用法一样 用来 保存发送方的网络信息结构体的
返回值:成功 实际接收的字节数失败 -1 重置错误码recvfrom函数用在UDP中是不会返回0

(二)sendto

#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
功能:向套接字上发送一条消息
参数:前 4 个参数用法和 send 函数的4个参数用法一模一样后 2 个参数用法和 connect 函数的后两个参数用法一样 用来 指定消息发给谁的
返回值:成功 实际发送的字节数失败 -1 重置错误码

三、实现一个简单的udp服务端和客户端

server.c

#include <my_head.h>int main(int argc, char const *argv[])
{if(3 != argc){printf("Usage: %s IPv4 port\n",argv[0]);exit(-1);}//创建套接字int sockfd = 0;if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0))){ERR_LOG("socket error");}//填充结构体struct sockaddr_in serveraddr;serveraddr.sin_family=AF_INET;serveraddr.sin_port=htons(atoi(argv[2]));//将命令行第二个参数转成int,并转成网络字节序serveraddr.sin_addr.s_addr=inet_addr(argv[1]);socklen_t serveraddrlen = sizeof(serveraddr);//绑定结构体if(-1 == bind(sockfd,(struct sockaddr *)&serveraddr,serveraddrlen)){ERR_LOG("bind error");}//客户信息结构体struct sockaddr_in clientaddr;socklen_t clientaddrlen = sizeof(clientaddr);while(1){//收发数据printf("等待接收数据...\n");char buff[128]={0};//保存发送方的网络结构体if(-1 == recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&clientaddr,&clientaddrlen)){ERR_LOG("recvfrom error");}printf("接收到数据[%s]\n",buff);strcat(buff,"--zyx");//指定发给谁if(-1 == sendto(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&clientaddr,clientaddrlen)){ERR_LOG("sendto error");}}return 0;
}

client.c

#include <my_head.h>int main(int argc, char const *argv[])
{if(3 != argc){printf("Usage: %s IPv4 port\n",argv[0]);exit(-1);}//创建套接字int sockfd = 0;if(-1 == (sockfd = socket(AF_INET,SOCK_DGRAM,0))){ERR_LOG("socket error");}//填充结构体struct sockaddr_in serveraddr;serveraddr.sin_family=AF_INET;serveraddr.sin_port=htons(atoi(argv[2]));serveraddr.sin_addr.s_addr=inet_addr(argv[1]);socklen_t serveraddrlen = sizeof(serveraddr);//可以不进行绑定,系统会自动绑定//收发数据char buff[128];while(1){printf("请输入数据:");scanf("%s",buff);if(-1 == sendto(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&serveraddr,serveraddrlen)){ERR_LOG("sendto error");}if(-1 == recvfrom(sockfd,buff,sizeof(buff),0,NULL,NULL)){ERR_LOG("recvfrom error");}printf("应答消息:[%s]\n",buff);}return 0;
}

四、实现tftp客户端协议

TFTP概述
TFTP:简单文件传送协议
最初用于引导无盘系统,被设计用来传输小文件

特点:
基于UDP协议实现
不进行用户有效性认证

数据传输模式:
octet:二进制模式
netascii:文本模式
mail:已经不再支持

需求分析
1、服务器在69号端口等待客户端的请求
2、服务器若批准此请求,则使用临时端口与客户端进行通信
3、每个数据包的编号都有变化(从1开始)
4、每个数据包都要得到ACK的确认如果出现超时,则需要重新发送最后的包(数据或ACK)
5、数据的长度以512Byte传输
6、小于512Byte的数据意味着传输结束

注意点
1.tftp服务器仅在69号端口接收客户端的请求,批准请求后,使用临时端口与客户端进行通信
2.每个数据包都要得到ACK的确认

代码实现

#include <my_head.h>int main(int argc, char const *argv[])
{if(2 != argc){printf("Usage: %s IPv4\n",argv[0]);exit(-1);}//创建套接字int socketfd = 0;if(-1 == (socketfd = socket(AF_INET,SOCK_DGRAM,0))){ERR_LOG("socket error");}//填充结构体struct sockaddr_in clentaddr;clentaddr.sin_family=AF_INET;clentaddr.sin_port=htons(69);clentaddr.sin_addr.s_addr=inet_addr(argv[1]); //字符串转四字节网络序整型socklen_t clentlen = sizeof(clentaddr);//发送请求char buff[600]={0};char filename[20]={0};printf("请输入想要下载的文件:");scanf("%s",filename);int dest_fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);//组装请求数据包int nbytes = sprintf(buff,"%c%c%s%c%s%c",0,1,filename,0,"octet",0);if(-1 == sendto(socketfd,buff,nbytes,0,(struct sockaddr *)&clentaddr,clentlen)){ERR_LOG("sendto error");}unsigned short option=0;unsigned short node =0;char data[512]={0};char ack[4];while(1){//接收服务器数据memset(buff, 0, sizeof(buff));memset(data, 0, sizeof(data));nbytes = recvfrom(socketfd,buff,sizeof(buff),0,(struct sockaddr *)&clentaddr,&clentlen);//解析数据(网络字节序)option = *(unsigned short *)buff;//操作码node = *(unsigned short *)(buff+2);//块编号strncpy(data,buff+4,nbytes-4);if(5 == ntohs(option)){//说明出错了printf("差错码:%d; 差错信息:%s\n",ntohs(node),buff);}else if(3 == ntohs(option)){printf("已接收到数据\n");//说明发送过来数据了,组装应答数据包memset(ack,0,4);ack[0]=0;ack[1]=4;*(unsigned short *)(ack+2)=node;//发送ACKif(-1 == sendto(socketfd,ack,4,0,(struct sockaddr *)&clentaddr,clentlen)){ERR_LOG("sendto error");}//写入文件中if(-1 == write(dest_fd,data,nbytes-4)){ERR_LOG("write error");}}if(nbytes < 516)//数据包内容不足512字节,说明文件拷贝完毕break;}printf("Download over\n");close(dest_fd);close(socketfd);return 0;
}

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

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

相关文章

Spring-事件

Java 事件/监听器编程模型 设计模式-观察者模式的拓展 可观察者对象(消息发送者) Java.util.Observalbe观察者 java.util.Observer 标准化接口(标记接口) 事件对象 java.util.EventObject事件监听器 java.util.EventListener public class ObserverDemo {public static vo…

Spring IoC【控制反转】DI【依赖注入】

文章目录 控制反转&#xff08;IoC&#xff09;依赖注入&#xff08;DI&#xff09;IoC原理及解耦IoC 容器的两种实现BeanFactoryApplicationContext IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&…

解放双手 免费AI编程工具---Fitten Code

前言 相信大家在2023年后听说了不少的关于人工智能的话题&#xff0c;对于这种全新的科技又好奇又恐惧&#xff0c;今天我们来见识下一个在VS中的AI代码工具吧。 配置环境 安装 首先我们找到管理扩展&#xff0c;然后再搜索Fitten Code下载安装。 我这里已经下好过了&#xff…

MacOS系统搭建Appium自动化测试环境

一、Appium简介 1.1 什么是APPium APPium是一个开源测试自动化框架,适用于原生、混合或移动Web应用程序的自动化测试工具。 APPium使用WebDriver协议驱动iOS、Android等应用程序。 APPium具有如下特点: 支持多平台(Android、iOS等)。支持多语言(python、java、ruby、js…

【每日刷题】Day67

【每日刷题】Day67 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 23. 合并 K 个升序链表 - 力扣&#xff08;LeetCode&#xff09; 2. 1189. “气球” 的最大数量 - …

网络安全 - kali 安装

文章目录 Kali 安装教程下载镜像 Kali 安装教程 下载镜像 kali-images安装包下载_开源镜像站-阿里云 (aliyun.com) 下载对应镜像&#xff08;自己挑&#xff09; 打开本机 cmd 并输入一下命令 ipconfig找到 NAT 模式的 IP 地址并从虚拟机中 ping

6月15号作业

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0…

一键掌控,4G红外插座引领智能生活新潮流!

随着科技的进步&#xff0c;市场上出现大量带语音、手机APP可控制的智能插座产品&#xff0c;由此可看出客户对产品的功能要求也越来越高&#xff0c;追求舒适的体验感&#xff0c;特别是对操控性的要求越来越高。但是目前大部分红外遥控插座均为WiFi插座类型&#xff0c;WiFi红…

gitlab仓库中用git bash生成不是默认路径的ssh秘钥

使用命令 ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 会在默认路径生成秘钥&#xff0c;&#xff08;C:\Users\用户\.ssh\&#xff09; 想要修改默认路径使用如下命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"…

【吉林大学Java程序设计】第11章:网络编程技术

第11章&#xff1a;网络编程技术 1.网络协议概述2.网络类及应用&#xff08;1&#xff09;InetAddress类&#xff08;2&#xff09;ServerSocket类&#xff08;3&#xff09;Socket类基于TCP的点对点通信基于TCP的点对面通信&#xff08;一个服务器&#xff0c;多个客户端&…

如何通过数据库与AI实现以图搜图?OceanBase向量功能详解

OceanBase支持向量数据库的基础能力 当前&#xff0c;数据库存储系统与人工智能技术的结合&#xff0c;可以体现在两个主要的应用方向上。 一、近似搜索。它利用大语言模型&#xff08;LLM&#xff0c;简称大模型&#xff09;的嵌入&#xff08;embedding&#xff09;技术&am…

环境科学SCI期刊,IF=8.5+,期刊发展势头非常好

一、期刊名称 SUSTAINABLE DEVELOPMENT 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;环境科学与生态学 影响因子&#xff1a;8.562 中科院分区&#xff1a;2区 三、期刊征稿范围 该期刊是一本跨学科出版物&#xff0c;旨在解决和讨论实现可持续发展的…

硬件开发笔记(十八):核心板与底板之间的连接方式介绍说明:板对板连接器

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139663096 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

最佳Google Chrome扩展和Mozilla Firefox扩展自动解决验证码

在这个信息爆炸的时代&#xff0c;我们每天都要处理大量的在线内容&#xff0c;验证码已成为不可避免的挑战。尽管它们旨在保护网站安全&#xff0c;但也常常成为我们获取信息的障碍。那么&#xff0c;有没有更简单的方法绕过这些验证码呢&#xff1f;答案是肯定的。通过使用一…

算法之分治

分而治之 分治法所能解决的问题一般具有以下几个特征&#xff1a; 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的子问题&#xff0c;即该问题具有最优子结构性质 3) 利用该问题分解出的子问题的解可以合并为该问题的解 4) 该问题所分…

ubuntu gitlab 部署 私有git库

我的版本 ubuntu-22.04.2-live-server-amd64 GitLab 社区版 v17.0.1 注意剩余硬盘需要3GB以上 一、更新软件 sudo apt update二、gitLab 需要一些依赖项才能正常运行 sudo apt install -y curl openssh-server ca-certificates postfix1、出现邮件 选择 “Internet Site”并…

数据库原理(关系数据库规范化理论)——(4)

一、关系模式规范化的必要性 1.关系可能出现的问题 数据冗余大&#xff1b;插入异常&#xff1b;删除异常&#xff1b;更新异常&#xff1b; 2.关系模式应满足的基本要求 元组的每个分量必须是不可分割的数据项&#xff1b;数据库中的数据冗余应尽可能少&#xff1b;不要出…

Neo4j Desktop界面认识以及数据库备份与还原

Neo4j Desktop界面认识以及数据库备份与还原 neo4j 版本信息&#xff1a;Neo4j Desktop Version 1.5.9&#xff1b;neo4j 5.12.0 系统信息&#xff1a;windows 11 Neo4j Desktop 界面 每个 Project 下可以有多个 DBMS&#xff0c;而每个 DBMS 中默认有 system 和 neo4j (def…

SQL Server中CROSS APPLY连接操作

在 SQL Server 中&#xff0c;CROSS APPLY 是一个连接操作&#xff0c;它类似于 INNER JOIN&#xff0c;但有一些关键差异&#xff0c;特别是在处理表值函数&#xff08;TVF&#xff09;、行集函数或子查询时。CROSS APPLY 返回对于外部查询中的每一行&#xff0c;在内部查询或…

LabVIEW_OPC读取PLC数据

使用OPCDemo_西门子 Demo位置Program Files \ National Instruments \ Shared \ NI OPC Servers \ V5 \ Projects \ simdemo.opf. 使用共享变量的方式读取数据 1.Labview项目中新建IO服务器 选择OPC Client 选择NI OPC Server Labview会创建一个Lib库对OPC客户端进行管理。…