客户端下载

news/2025/2/22 18:11:37/

主函数:

#include "head.h"
typedef unsigned short ushort;
int main(int argc, const char *argv[])
{//创建套接字int sfd = socket(AF_INET,SOCK_DGRAM,0);if(sfd < -1){ERR_MSG("socket");return -1;}//填充服务器地址信息struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);socklen_t addrlen = sizeof(sin);int flag = -1;while(1){printf("选择操作(1:下载;2:上传;3:退出\n)");scanf("%d",&flag);while(getchar()!=10);if(1 == flag)DownLoad(sfd,addrlen,sin);else if(2 == flag)updata(sfd,addrlen,sin);else if(3 == flag)break;}close (sfd);return 0;
}

 库函数:

#include "head.h"
void DownLoad(int sfd,socklen_t addrlen,struct sockaddr_in sin)
{char data[516] = "";ssize_t dataSize = -1;//打开文件并获得流指针printf("输入文件名:\n");fgets(data,sizeof(data),stdin);data[strlen(data)-1] = 0;FILE*fp = fopen(data,"w+");if(NULL == fp){ERR_MSG("fopen");exit(-1);}bzero(data,sizeof(data));do{size_t size = ReqBag(data,1);if(sendto(sfd,(void*)data,size,0,(struct sockaddr*)&sin,addrlen) < 0){ERR_MSG("sendto");exit(-1);}dataSize = recvfrom(sfd,(void*)data,sizeof(data),0,(struct sockaddr*)&sin,&addrlen);	if(dataSize < 0){ERR_MSG("recvfrom");exit(-1);}if(*(short *)data == htons(3))break;else if(*(short*)data == htons(5)){puts(data+4);}}while(1);unsigned short num = -1;do{if(htons(num+1) == *(unsigned short*)(data + 2)){fwrite((void*)(data+4),1,dataSize-4,fp);}ACKbag(sfd,addrlen,sin,++num);if(dataSize < 516){printf("下载完成\n");fclose(fp);return ;}dataSize = recvfrom(sfd,(void*)data,sizeof(data),0,(struct sockaddr*)&sin,&addrlen);	if(dataSize < 0){ERR_MSG("recvfrom");exit(-1);}if(*(short *)data == 5){puts(data+4);}}while(1);}
void updata(int sfd,socklen_t addrlen,struct sockaddr_in sin)
{char data[516] = "",ackbuf[4] = "";ssize_t dataSize = -1;unsigned short num = 0;ssize_t res = -1;//打开文件并获得流指针printf("输入文件名:\n");fgets(data,sizeof(data),stdin);data[strlen(data)-1] = 0;FILE*fp = fopen(data,"r");if(NULL == fp){ERR_MSG("fopen");exit(-1);}bzero(data,sizeof(data));ReqBag(data,2);//封请求包do{if(sendto(sfd,data,516,0,(struct sockaddr*)&sin,addrlen) < 0)//发送请求包,只要前面字段符合协议服务器就认{ERR_MSG("sendto");exit(-1);}res = recvfrom(sfd,data,sizeof(data),0,(struct sockaddr*)&sin,&addrlen);//收回包if(res < 0){ERR_MSG("recvfrom");exit(-1);}if(insp_recdata(data,num))//验回包,无误退出循环,有误继续上一步发送操作{num++;bzero(data,sizeof(data));break;}}while(1);//发送请求包并检验收到的ACKwhile(1)//发送数据包{res = getData(fp,data);//从文件中读取数据if(res == 0){printf("上传完成\n");fclose(fp);break;}while(1)//发送读取到的数据并检验回包,回包出错则重新发送上一个数据包并再次检验{sDataBag(sfd,addrlen,sin,num,data);//发送数据包,num:块编号res = recvfrom(sfd,ackbuf,sizeof(ackbuf),0,(struct sockaddr*)&sin,&addrlen);if(res < 0){ERR_MSG("recvfrom");exit(-1);}//收回包if(insp_recdata(ackbuf,num))//验证回包{bzero(data,sizeof(data));num++;break;}}}}
long ReqBag(char *data,char rw)//封装请求包
{char buf[128];printf("输入目标文件文件名\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = 0;int size = sprintf(data,"%c%c%s%c%s%c",0,rw,buf,0,"octet",0);return (long)size;
}
//下载专用
void ACKbag(int sfd,socklen_t addrlen,struct sockaddr_in sin,unsigned short num)//回包
{char buf[4] = "";*(unsigned short*)buf = htons(4);*(unsigned short*)(buf+2) = htons(num);sendto(sfd,(void*)buf,4,0,(struct sockaddr*)&sin,addrlen);
}
///上传专用///
int insp_recdata(char data[],unsigned short num)//验证回包数据,无误返回1,重复返回0,错误直接退出进程
{if(*(unsigned short *)data == htons(5)){puts(data+4);printf("%d\n",__LINE__);exit(-1);}else if(*(unsigned short*)(data+2) == htons(num)){return 1;}elsereturn 0;
}size_t getData(FILE*fp,char data[])//从文件中获取数据并存入数据包数据段中
{size_t res = fread(data+4,1,512,fp) ;if(res < 0){ERR_MSG("fread");exit(-1);}return res;
}void sDataBag(int sfd,socklen_t addrlen,struct sockaddr_in sin,unsigned short num,char data[])//封装包头段并发送数据
{//封装包头段*(unsigned short*)data = htons(3);*(unsigned short*)(data+2) = htons(num);//发送数据,发送失败直接退进程if(sendto(sfd,data,516,0,(struct sockaddr*)&sin,addrlen) < 0){ERR_MSG("sendto");exit(-1);}
}

头文件:  

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include<stdlib.h>
#define ERR_MSG(msg) do{\fprintf(stderr,"line:%d",__LINE__);\perror(msg);\
}while(0)
#define PORT 69 //1024~49151
#define IP "192.168.31.164"
void DownLoad(int sfd,socklen_t addrlen,struct sockaddr_in sin);
long ReqBag(char *data,char rw);void updata(int sfd,socklen_t addrlen,struct sockaddr_in sin);
void ACKbag(int sfd,socklen_t addrlen,struct sockaddr_in sin,unsigned short num);
int insp_recdata(char data[],unsigned short num);
size_t getData(FILE*fp,char data[]);
void sDataBag(int sfd,socklen_t addrlen,struct sockaddr_in sin,unsigned short num,char data[]);
#endif

 流程图:


http://www.ppmy.cn/news/333294.html

相关文章

我与CSDN的一周年纪念日、

我与CSDN的一周年&#xff1a; 去年的今日&#xff0c;我第一次了解到CSDN这个宝藏软件&#xff0c;各个创作者们积极分享自己的知识&#xff0c;开源是一种情怀&#xff0c;于此&#xff0c;我也加入了CSDN的大家庭&#xff0c;成为CSDN创作者&#xff0c;不仅可以沉淀自己的知…

【腾讯云十周年感恩钜惠】

从2010到2020 从开始对外提供云服务 到跻身全球七大首选云服务商 十年征途 腾讯云全球服务器 总台数突破100万台 合作伙伴超100家 带宽峰值突破100T 十年开拓 腾讯云紧握时代脉搏 实现了自身跨越式发展 十年守护 感恩用户的陪伴和包容 与我们共同成长 2020年 新起点&#xff0c…

云+社区3周年,程序员好礼送不停!

2017年10月&#xff0c;云社区正式对外发布&#xff0c;从最开始的技术博客到现在拥有专栏等多个社区产品&#xff0c;我们初心不变&#xff0c;只为更好地服务于开发者。 值得开心的是&#xff0c;今天社区迎来了 3 周年&#xff0c;想想也挺快的&#xff0c;再过97年&#xf…

终于来了 Windows10服务器版低调上线

终于来了&#xff0c;近日微软低调上线了Windows10服务器版&#xff0c;即Windows Server 2016系统。 实际上&#xff0c;上月末&#xff0c;微软就已经面向大客户OEM伙伴分发了Windows Server 2016正式版ISO镜像&#xff0c;现在则是全面开放下载使用。 Windows Server 2016带…

redis 客户端

几款连接redis的客户端(GUI客户端)&#xff0c;下面记录了我使用的几款 一、Redis 客户端 1、命令行工具 命令行 (建议使用&#xff0c;简单) 比如windows的cmd和Linux、Mac的Terminal&#xff0c;虽然最简单好用。 必须保证有 redis-cli 命令(windows 是 redis-cli.exe)&am…

c++客户端

socket http 代理IP销售#include "pch.h" #include <iostream> #include <cstdio> #include<iostream> #include<string> #include<WinSock2.h> #pragma comment(lib,"ws2_32.lib") #include <time.h> #include <…

客户端

客户端&#xff08;Client&#xff09;或称为用户端&#xff0c;是指与服务器相对应&#xff0c;为客户提供本地服务的程序。一般安装在普通的客户机上&#xff0c;需要与服务端互相配合运行。因特网发展以后&#xff0c;较常用的用户端包括了如万维网使用的网页浏览器&#xf…

一周年

人的一生不知道有多少个日子是需要特殊去记忆的&#xff0c;一周年其实就是从去年的今天到现在&#xff0c;之所以叫一周年可能就因为它是个不寻常的日子&#xff0c;没有什么语言来表达它&#xff0c;去年的今天起的很早去赶车&#xff0c;去做一件这辈子第一次做就不会再做的…