网络编程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以上
今日思维导图

相关文章:
网络编程day03(UDP中的connect函数、tftp)
今日任务:tftp的文件上传下载(服务端已经准备好) 服务端(已上传) 客户端: 代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h…...
flarum 论坛 User Statistics插件修改
此插件在中国使用日期不是很理想,于是决定修改代码 下面是插件信息: User Statistics A Flarum extension. Add some user statistics in flarum posts, this extension require clarkwinkelmann/flarum-ext-likes-received and will be installed au…...
阿里云产品试用系列-容器镜像服务 ACR
阿里云容器镜像服务(简称 ACR)是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效,与容器服务 ACK 无缝集成,帮助企业…...
Langchain里的“记忆力”,让AI只记住有用的事
今天要讲以下内容: 1.ConversationBufferWindowMemory:基于一个固定长度的滑动窗口的“记忆”功能 2.ConversationSummaryMemory:总结对话“记忆”功能 3.ConversationSummaryBufferMemory:上面两个的结合,超过一定…...
从零开始的LINUX(一)
LINUX本质是一种操作系统,用于对软硬件资源进行管理,其管理的方式是指令。指令是先于图形化界面产生的,相比起图形化界面,指令显然更加难以理解,但两者只是形式上的不同,本质并没有区别。 简单的指令&…...
CH34X-MPHSI高速Master扩展应用—I2C设备调试
一、前言 本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展I2C总线的用法,除…...
记一次正式环境升级docker服务基础进行版本异常
因为服务的httpd和tomcat基础镜像版本比较旧,漏洞多,需要升级至最新版本。在本地环境和测试环境都是直接将dockerfile中的FROM基础镜像升级至最新: httpd:由httpd:2.4.52-alpine升级至httpd:2.4.57 tomcat:由4年前的…...
leetcode面试经典150题第一弹(一)
leetcode面试经典150题第一弹 一、合并俩个有序数组(难度:简单) 题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并…...
VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001
VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001 由于第12代英特尔酷睿处理器的16核/24线程配置,Nuvo-9000型号与之前的平台相比,性能大幅提升。它们还支持新的DDR5内存标准,以获得更多内存带宽…...
01-Zookeeper特性与节点数据类型详解
上一篇: 在了解Zookeeper之前,需要对分布式相关知识有一定了解,什么是分布式系统呢?通常情况下,单个物理节点很容易达到性能,计算或者容量的瓶颈,所以这个时候就需要多个物理节点来共同完成某项…...
TP6 TP8 使用阿里官方OSS SDK方法
安装 composer require aliyuncs/oss-sdk-php 官网:GitHub - aliyun/aliyun-oss-php-sdk: Aliyun OSS SDK for PHP 二、PHP简单上传 官网教程:如何进行字符串上传和文件上传_对象存储 OSS-阿里云帮助中心 引入 use OSS\OssClient; use OSS\Core\OssE…...
SkyWalking分布式链路追踪学习
为什么要用分布式链路追踪 实际生产中,面对几十个、甚至成百上千个的微服务实例,如果一旦某个实例发生宕机,如果不能快速定位、提交预警,对实际生产造成的损失无疑是巨大的。所以,要对微服务进行监控、预警࿰…...
git revert 撤销之前的提交
git revert 用来撤销之前的提交,它会生成一个新的 commit id 。 输入 git revert --help 可以看到帮忙信息。 git revert commitID 不编辑新的 commit 说明 git log 找到需要撤销的 commitID , 然后执行 git revert commitID ,会提示如下…...
rk3568环境配置和推理报错: RKNN_ERR_MALLOC_FAIL
前言 最近在部署算法在板子侧遇到的一些问题汇总一下: 一、版本问题 经过测试现在将自己环境配置如下: 本地linux安装rknn-toolkit2-1.5.0 本地Linux使用的miniconda新建的一个python虚拟环境(自行网上查找相关方法) 安装好自…...
网络工程师基础笔记(一)
一、接入网 接入网,是指将端系统物理连接到边缘路由器的网络。 (1)家庭接入:数字用户线(DSL)、电缆、光纤到户(FTTH)卫星和拨号接入。 (2)企业(家庭)接入&…...
Postman应用——Headers请求头设置
文章目录 Header设置Header删除或禁用Header批量编辑Header预设添加 一般在接口需要校验签名时,Headers请求头用来携带签名和生成签名需要的参数,在Postman也可以设置请求头在接口请求时携带参数。 Header设置 说明: Key:Header…...
人人都是项目经理-项目管理概述(一)
一、重新认识项目管理 1. 什么是项目 项目(Project),是为提供某项独特的产品(交付物),服务或成果所做的临时性努力。 – PMBOK指南 项目是指一系列独特的、复杂的并相互关联的活动,这些活动有着…...
浅谈基于物联网的医院消防安全管理
安科瑞 华楠 摘 要:医院消防物联网将原本与网络无关的消防设施和网络结合起来,将消防监督管理、防火灭火所需的相关信息进行汇总,可以让医院更加轻松地发现和处理医院的警情信息,降低火灾发生频率。 关键词:物联网技…...
户用储能争斗:华宝新能“稳”、正浩科技“快”、安克创新“急”
便携式储能市场一片红海,户用储能(家用储能)成为储能企业新的“格斗场”。 过去两年,房车游、户外旅行、露营等旅游项目热度攀升,户外用电需求与日俱增,嗅觉敏锐的资本方相继加码便携储能市场,越…...
【面试篇】集合相关高频面试题
目录 1. ArrayList和LinkedList的区别?2. HashMap和HashTable的区别?1. ArrayList和LinkedList的区别? ArrayListLinkedList数据结构数组链表插入和删除在中间插入或删除元素时需要移动数组中的其他元素,时间复杂度为O(n)只需要调整指针,时间复杂度为O(1)访问元素通过索引…...
WordPress主题开发实战:从零开始搭建你的第一个自定义主题(2024最新版)
WordPress主题开发实战:从零开始搭建你的第一个自定义主题(2024最新版) 如果你正准备踏入WordPress主题开发的世界,这篇文章将带你从零开始构建一个完整的自定义主题。不同于简单的仿制或修改现有主题,我们将深入探讨如…...
LyricsX:突破平台限制,重构macOS歌词体验的开源解决方案
LyricsX:突破平台限制,重构macOS歌词体验的开源解决方案 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX 在流媒体音乐蓬勃发展的今天,音乐爱好者们却常…...
OpenSSH用户枚举漏洞(CVE-2018-15473)修复实战:从检测到升级的完整指南
OpenSSH用户枚举漏洞(CVE-2018-15473)修复实战:从检测到升级的完整指南 在当今的网络安全环境中,SSH服务作为远程管理服务器的标准协议,其安全性直接关系到整个系统的防护水平。2018年曝光的OpenSSH用户枚举漏洞(CVE-2018-15473)虽然CVSS评分…...
Python多进程+ZeroMQ+内存映射=真无锁?资深架构师用17个生产事故告诉你为什么92%的“去GIL”方案在高并发下静默失败
第一章:Python无锁GIL环境下的并发模型避坑指南Python 的全局解释器锁(GIL)长期被误认为是“无锁”环境,实则恰恰相反——GIL 是 CPython 解释器中一把严格的互斥锁,它确保任意时刻仅有一个线程执行 Python 字节码。所…...
实战指南:用快马为django项目生成定制化vmware开发环境,开箱即用
实战指南:用快马为Django项目生成定制化VMware开发环境,开箱即用 在实际开发场景中,虚拟机环境需要与具体项目需求紧密结合。最近我在做一个Django项目时,发现每次换电脑或重装系统都要重新配置开发环境,特别浪费时间…...
23种设计模式 - 组合模式(Composite)
组合模式(Composite)—— 文件夹套文件夹,统一操作 大白话解释 你的电脑里: 📄 文件(不能再包含东西)📁 文件夹(可以装文件,也可以装文件夹) &…...
3步解决HEIC预览难题:面向Windows用户的高效缩略图工具
3步解决HEIC预览难题:面向Windows用户的高效缩略图工具 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 在数字影像管理中&…...
紧固件包装机有哪些类型?自动化包装设备全解析_FES 2026上海紧固件展
2026第十六届上海紧固件专业展(Fastener Expo Shanghai 2026)将于6月24日至26日在国家会展中心(上海)举行。作为紧固件行业的重要展示窗口,本届展会将重点呈现制造端与后道环节的智能化升级,其中࿰…...
Mojo调用Python模块性能翻倍?深度剖析混合编程内存管理、GIL绕过与ABI兼容性(附实测基准数据)
第一章:Mojo与Python混合编程案例源码分析Mojo 作为兼具 Python 兼容性与系统级性能的新一代编程语言,其与 Python 的混合编程能力是实际工程落地的关键。以下通过一个典型场景——在 Python 主程序中调用 Mojo 实现的高性能向量加法函数——展开源码级剖…...
Go Mutex 与 RWMutex 性能对比
在Go语言并发编程中,Mutex(互斥锁)和RWMutex(读写锁)是两种常用的同步机制。它们的性能差异直接影响高并发场景下的程序效率。本文将从多个角度对比两者的性能表现,帮助开发者根据实际需求选择合适的锁机制…...
