网络编程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)访问元素通过索引…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
从物理机到云原生:全面解析计算虚拟化技术的演进与应用
前言:我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM(Java Virtual Machine)让"一次编写,到处运行"成为可能。这个软件层面的虚拟化让我着迷,但直到后来接触VMware和Doc…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
FOPLP vs CoWoS
以下是 FOPLP(Fan-out panel-level packaging 扇出型面板级封装)与 CoWoS(Chip on Wafer on Substrate)两种先进封装技术的详细对比分析,涵盖技术原理、性能、成本、应用场景及市场趋势等维度: 一、技术原…...
