网络编程day03(UDP中的connect函数、tftp)

今日任务:tftp的文件上传下载(服务端已经准备好)

服务端(已上传)

 客户端:

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <fcntl.h>//自定义报错提示
#define ERR_MSG(msg) do{\fprintf(stderr,"__%d__",__LINE__);\perror(msg);\
}while(0)//#define SER_PORT 69
//#define SER_IP "192.168.125.74"
#define SER_PORT 69
#define SER_IP "192.168.125.225"
int do_upload(int cfd,struct sockaddr_in addr);
int do_download(int cfd,struct sockaddr_in addr);
int main(int argc, const char *argv[])
{//1.创建socket套接字int cfd=socket(AF_INET,SOCK_DGRAM,0);if(cfd<0){ERR_MSG("socket");return -1;}puts("socket success");//3.接受和发送消息//目标地址信息struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(SER_PORT);addr.sin_addr.s_addr=inet_addr(SER_IP);socklen_t addrlen=sizeof(addr);//记录接受信息的目标地址信息struct sockaddr_in recv_addr;socklen_t recv_addrlen=sizeof(recv_addr);while(1){puts("---------------------------------");puts("------------1.上传---------------");puts("------------2.下载---------------");puts("------------3.退出---------------");puts("---------------------------------");puts("请选择>>");char choice;choice=getchar();while(getchar()!='\n');//循环吸收垃圾字符switch(choice){case '1':do_upload(cfd,addr);break;case '2':puts("download");do_download(cfd,addr);break;case '3':goto END;}}
END:/*char buf[128];while(1){printf("请输入>>>");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';int send_res=sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&addr,addrlen);if(send_res<0){ERR_MSG("sendto");return -1;}puts("sendto success");if(strcmp(buf,"quit")==0)break;bzero(buf,sizeof(buf));int recv_res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&recv_addr,&recv_addrlen);if(recv_res<0){ERR_MSG("recvfrom");return -1;}puts("recvfrom success");printf("[%s:%d]:%s\n",inet_ntoa(recv_addr.sin_addr),ntohs(recv_addr.sin_port),buf);	}*///4.关闭close(cfd);return 0;
}
int do_upload(int cfd,struct sockaddr_in addr){printf("请输入要上传的文件名.>>>");char name[20]="";scanf("%s",name);while(getchar()!=10);//组下载协议char buf[516]="";//操作码unsigned short *p1=(unsigned short*)buf;*p1=htons(2);//文件名char *p2=buf+2;strcpy(p2,name);//0//模式char *p4=p2+strlen(name)+1;strcpy(p4,"octet");//0int size=2+strlen(name)+1+strlen(p4)+1;//printf("buf==%s;size==%d",buf,size);//发送协议给服务器if(sendto(cfd,buf,size,0,(struct sockaddr*)&addr,sizeof(addr))<0){ERR_MSG("sendto");return -1;}puts("send upload protocal success");//打开一个文件,输入int fd=open(name,O_RDONLY);if(open<0){ERR_MSG("open");return -1;}unsigned short bNum=1;//重新定义一个地址的结构体,接受服务端传来的临时地址struct sockaddr_in dest_addr;socklen_t addrlen=sizeof(dest_addr);if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&dest_addr,&addrlen)<0){ERR_MSG("recvfrom");return -1;}while(1){//组包:操作码+块编号+数据bzero(buf,sizeof(buf));unsigned short *opNum=(unsigned short*)buf;*opNum=htons(3);unsigned short *blockNum=opNum+1;*blockNum=htons(bNum);char* msg=buf+4;int read_res=read(fd,msg,512);if(read<0){ERR_MSG("read");}//发包ssize_t sendto_res=sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&dest_addr,addrlen);if(sendto_res<0){ERR_MSG("sendto");return -1;}printf("sendto_res=%ld\n----",sendto_res);//接受ackif(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&dest_addr,&addrlen)<0){ERR_MSG("recvfrom");return -1;}opNum=(unsigned short*)buf;blockNum=opNum+1;if(ntohs(*opNum)==5){puts("操作码错误");printf("%d %d:%s",ntohs(*opNum),ntohs(*blockNum),msg);}else if(ntohs(*opNum)==4){if(ntohs(*blockNum)==bNum){puts("ACK correct");}else{puts("ACK incorrect");return -1;}}bNum++;if(read_res<512){printf("bNUm==%d\n",bNum);puts("upload done");break;}}close(fd);}
int do_download(int cfd,struct sockaddr_in addr){printf("请输入要下载的文件名.>>>");char name[20]="";scanf("%s",name);while(getchar()!=10);//组下载协议char buf[516]="";//操作码unsigned short *p1=(unsigned short*)buf;*p1=htons(1);//文件名char *p2=buf+2;strcpy(p2,name);//0//模式char *p4=p2+strlen(name)+1;strcpy(p4,"octet");//0int size=2+strlen(name)+1+strlen(p4)+1;//printf("buf==%s;size==%d",buf,size);//发送协议给服务器if(sendto(cfd,buf,size,0,(struct sockaddr*)&addr,sizeof(addr))<0){ERR_MSG("sendto");return -1;}puts("send download protocal success");//新建打开一个文件,等下写入int fd=open(name,O_WRONLY|O_CREAT|O_TRUNC,0664);if(fd<0){ERR_MSG("open");return -1;}//重新定义一个地址的结构体,接受服务端传来的临时地址struct sockaddr_in dest_addr;socklen_t addrlen=sizeof(dest_addr);while(1){//接受数据包int recv_res=recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&dest_addr,&addrlen);if(recv_res<0){ERR_MSG("recvfrom");return -1;}unsigned short* opNum=(unsigned short*)buf;unsigned short* blockNum=opNum+1;char * msg=(char *)(blockNum+1);if(ntohs(*opNum)==5){puts("操作码错误");printf("%d %d:%s",ntohs(*opNum),ntohs(*blockNum),msg);}else if(ntohs(*opNum)==3){int wr_res=write(fd,msg,recv_res-4);if(wr_res<0){ERR_MSG("write");}else if(wr_res<512){puts("recvfrom done");break;}}//组ACK包,吾把buf当做ack来使*opNum=htons(4);//回复ACK包sendto(cfd,buf,4,0,(struct sockaddr*)&dest_addr,addrlen);bzero(buf,sizeof(buf));}//
}

运行结果:

不知道是网络的问题还是代码的问题,上传很慢,代码很快正常运行结束了,但是tftp服务端下载到win上很慢,7kb的也要5s以上

今日思维导图

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

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

相关文章

vue实现进度条+背景定位

最近在做一个数字孪生项目&#xff0c;用于展示地铁车辆的进场动画及部件&#xff0c;使用的vueunity&#xff0c;但是 unity模型在加载完成之前会有个加载进度条&#xff0c;页面背景色是黑色&#xff0c;中间只有个一进度条框 可以看到很单调很丑&#xff0c;并且客户也不满…

Linux上的Pip和Python升级指南

在Linux系统上&#xff0c;保持Pip和Python版本的最新状态对于顺利进行Python开发至关重要。通过升级Pip和Python&#xff0c;你可以享受到最新的功能、修复的bug以及提升的开发效率。本文将为你提供在Linux上升级Pip和Python的详细指南&#xff0c;助你打造更强大的开发环境。…

✔ ★ 算法基础笔记(Acwing)(六)—— 贪心【java版本】

贪心 一、 区间问题1. 区间选点2. 最大不相交区间数量3. 区间分组(用 堆top 代表区间 头头)POJ3614Sunscreen(优先队列贪心) 4. 区间覆盖 二、哈夫曼树1. 合并果子 三、排序不等式1. 排队打水 四、绝对值不等式货仓选址 五、推公式耍杂技的牛 一、 区间问题 1. 区间选点 原题…

气传导和骨传导耳机哪个好?气传导耳机好用吗?气传导耳机推荐

​气传导和骨传导耳机都是不入耳设计&#xff0c;骨传导是通过振动颅骨传达声音信号 骨传导耳机是一种能够通过振动颅骨来传达声音信号的耳机&#xff0c;其原理是利用骨传导技术&#xff0c;将声音信号通过颅骨传达到内耳&#xff0c;从而实现听觉效果&#xff0c;不过长时间佩…

YashanDB向量化执行引擎如何给海量数据分析提速

作者介绍&#xff1a;李伟超&#xff0c;数据库系统架构师&#xff0c;YashanDB架设技术开发负责人&#xff0c;10年以上数据库内核技术开发经验。 *全文4510个字&#xff0c;阅读时长约11分钟。 背景 海量数据OLAP场景&#xff0c;通常具有数据规模大、查询复杂度高、处理速…

9月27日星期三今日早报简报微语报早读

9月27日&#xff0c;星期三&#xff0c;早报简报微语早读分享。 1、兰州&#xff1a;拟明年起奖励医保参保人连续缴费&#xff0c;提高其住院报销比例&#xff1b; 2、中国民办教育协会&#xff1a;10月15日起全面禁止校外培训系误读误解&#xff1b; 3、山西修订未成年人保…

外包干了3个月,技术退步明显。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;17年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

根据命令行参数动态导入模块或文件

需求 在命令行运行一个 python 文件&#xff0c;同时传入自定义参数&#xff1a; $ python main.py --nodeTable --actioncreate --data"{name: test2, is_sys_obj: False, encoding: UTF8,datconnlimit: -1, variables: []"希望 main.py 接收命令行参数&#xff0…

Flutter笔记:滚动之-无限滚动与动态加载的实现

Flutter笔记 无限滚动与动态加载的实现 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133342307 目 录…

Goby 漏洞发布|泛微 E-office flow_xml.php 文件 SORT_ID 参数 SQL 注入漏洞

漏洞名称&#xff1a;泛微 E-office flow_xml.php 文件 SORT_ID 参数 SQL 注入漏洞 English Name&#xff1a; Weaver E-office flow_xml.php file SORT_ID parameter SQL injection vulnerability CVSS core:7.8 影响资产数&#xff1a; 21632 漏洞描述&#xff1a; 泛微…

前端知识总结

在前端开发中&#xff0c;y x是一种常见的自增运算符的使用方式。它表示将变量x的值自增1&#xff0c;并将自增后的值赋给变量y。 具体来说&#xff0c;x是一种后缀自增运算符&#xff0c;表示将变量x的值自增1。而y x则是将自增前的值赋给变量y。这意味着在执行y x之后&am…

linux使用操作[2]

文章目录 版权声明网络传输ping命令wget命令curl命令端口linux端口端口命令和工具 进程管理查看进程关闭进程 主机状态top命令内容详解磁盘信息监控 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马程序员或相…

设计模式-迭代器模式

介绍 顺序访问一个集合使用者无需知道集合的内部结构&#xff08;封装&#xff09; 示例 常用的jQuery演示 <p>jquery each</p> <p>jquery each</p> <p>jquery each</p><script> var arr [1,2,3] var nodeList document.getEl…

【Unity】LODGroup 计算公式

Unity 在配置 LodGroup 时&#xff0c;其分级切换的计算方法是按照物体在相机视野中占据的比例计算的。在运行时&#xff0c;如果相机视野范围&#xff08;Field of View&#xff09;没有改变&#xff0c;那么这个值可以直接换算成物体距离相机的距离。这里就讨论下如何计算得到…

Jmeter——循环控制器中实现Counter计数器的次数重置

近期在使用Jmeter编写个辅助测试的脚本&#xff0c;用到了多个Loop Controller和Counter。 当时想的思路就是三个可变的数量值&#xff0c;使用循环实现&#xff1b;但第三个可变值的数量次数&#xff0c;是基于第二次循环中得到的结果才能确认最终次数&#xff0c;每次的结果…

华南理工大学电子与信息学院23年预推免复试面试经验贴

运气较好&#xff0c;复试分数90.24&#xff0c;电科学硕分数线84、信通83、专硕电子与信息74. 面试流程&#xff1a; 1&#xff1a;5min ppt的介绍。其中前2min用英语简要介绍基本信息&#xff0c;后3min可用英语也可用中文 介绍具体项目信息如大创、科研、竞赛等&#xff08…

AI指令百科全书:1000条AI指令,一次性全给你!

这是一位&#xff0c;国外博主哈桑 整理的&#xff0c;1000条ChatGPT实用指令&#xff0c;涵盖目前几乎所有的&#xff0c;主流提示需求。 全文超过40000字。 我把它们翻译成更适合大家理解的「中文版Prompt」&#xff0c;并根据具体的内容&#xff0c;拆解成一二级目录&…

Serlet API详解

目录 一、HttpServlet 1.1 处理doGet请求 1.2 处理doPost请求 二、HttpServletRequest 2.1 核心方法 三、HttpServletRespons 3.1 核心方法 一、HttpServlet 在编写Servlet代码的时候&#xff0c;首先第一步要做的就是继承HttpServlet类&#xff0c;并重写其中的某些方法 核心…

基于边缘智能网关的储充一体电站管理方案

在“2030碳达峰&#xff0c;2060碳中和”的目标下&#xff0c;我国持续加快推进能源转型&#xff0c;扩大新能源占比&#xff0c;全国各地都在部署建设光伏、储能、新能源汽车充电等应用。随着新能源汽车的广泛普及&#xff0c;充电站、充电桩的需求快速增加&#xff0c;行业也…

瑞芯微RK3568:Debian系统如何安装Docker

本文基于HD-RK3568-IOT评估板演示Debian系统安装Docker&#xff0c;该方法适用于RK356X全系产品。 HD-RK3568-IOT评估板基于HD-RK3568-CORE 工业级核心板设计&#xff08;双网口、双CAN、5路串口&#xff09;&#xff0c;接口丰富&#xff0c;适用于工业现场应用需求&#xff…