加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
gets.c 4.67 KB
一键复制 编辑 原始数据 按行查看 历史
SpaceX_zhao 提交于 2023-05-18 22:23 . alopex modify
#include "head.h"
#define int8_t char
#define uint8_t unsigned char
#define int32_t int
#define uint32_t unsigned int
#define int16_t short
#define uint16_t unsigned short
void hb_hex2ascii(uint8_t *hex, char *str, uint32_t len)
{
uint8_t value = 0;
uint32_t i;
int lower = 1;
if (str != NULL) {
for (i = 0; i < len; i++) {
if (lower == 1) {
value = 0;
value |= (*hex & 0xF0) >> 4;
value |= (*hex & 0x0F) << 4;
hex++;
lower = 0;
} else {
value = (value >> 4) & 0x0F;
lower = 1;
}
if ((value & 0x0F) <= 9) {
*str++ = '0' + (value & 0x0F);
} else {
*str++ = 'a' + (value & 0x0F) - 10;
}
}
}
}
// 小文件的接收
void recvMinFile(int sockfd, int fd, train_t train){
printf("小文件接收\n");
while(1){
bzero(&train, sizeof(train));
// 接收数据的长度
recvn(sockfd, &train.length, sizeof(train.length));
if(train.length == 0){
break;
}
// 接收内容
recvn(sockfd, train.data, train.length);
write(fd, train.data, train.length);
}
}
// 大文件的接收, mmap方式
void recvMaxFile(int sockfd, int fd, off_t filesize){
printf("大文件接收\n");
ftruncate(fd, filesize);
char *p = (char *)mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ERROR_CHECK(p, MAP_FAILED, "mmap");
recvn(sockfd, p, filesize);
munmap(p, filesize);
}
// 续传的接收
void recvAgain(int sockfd, int fd, off_t filesize, off_t offset){
printf("续传接收\n");
ftruncate(fd, filesize);
char *p = (char *)mmap(NULL, filesize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ERROR_CHECK(p, MAP_FAILED, "mmap");
recvn(sockfd, p+offset, filesize-offset);
munmap(p, filesize);
}
int recvFile(int sockfd, unsigned char *MD5, MYSQL* mysql, userProcess_t* usr){
train_t train1, train2, train3, train4;
// step1:接收文件名长度和文件名
bzero(&train1,sizeof(train1));
recvn(sockfd, &train1.length, sizeof(train1.length));
recvn(sockfd, train1.data, train1.length);
if(train1.length == 0){
recvn(sockfd, &train1.length, sizeof(train1.length));
recvn(sockfd, train1.data, train1.length);
}
// 打开文件,若不存在则新建文件
char newPath[33] = {0};
//memcpy(newPath,MD5,16);
for(int i=0; i<16; i++){
printf("%02x",MD5[i]);
}
printf("\n");
hb_hex2ascii(MD5, newPath, 32);
newPath[32]='\0';
printf("newPath = %s\n", newPath);
int fd = open(newPath, O_RDWR|O_CREAT, 0666);
ERROR_CHECK(fd, -1, "open");
// step2:接收文件总大小
bzero(&train2,sizeof(train2));
off_t fileSize;
recvn(sockfd, &train2.length, sizeof(train2.length));
recvn(sockfd, train2.data, train2.length);
memcpy(&fileSize, train2.data, sizeof(off_t));
// step3:发送initSize,对于文件的发送方相当于偏移量
bzero(&train3, sizeof(train3));
struct stat statbuf;
fstat(fd, &statbuf);
off_t initSize = statbuf.st_size;
printf("offset = %ld\n", initSize);
train3.length = sizeof(statbuf.st_size);
memcpy(train3.data, &statbuf.st_size, train3.length);
send(sockfd, &train3, sizeof(train3.length)+train3.length, MSG_NOSIGNAL);
if(initSize > 0){
// 续传的接收
recvAgain(sockfd, fd, fileSize, initSize);
}
else if(initSize == 0 && fileSize >= 100*1024*1024){
// 大文件接收
recvMaxFile(sockfd, fd, fileSize);
}
else if(initSize == 0 && fileSize < 100*1024*1024){
// 小文件接收
recvMinFile(sockfd, fd, train4);
}
printf("recv file done!\n");
// 接收完文件内容后lseek到开头
lseek(fd, 0, SEEK_SET);
// 非秒传模式,接收完文件后再计算接收方自己的md5码
MD5_CTX ctx;
MD5_Init(&ctx);
char buf[4096];
while(1){
bzero(buf, sizeof(buf));
ssize_t sret = read(fd, buf, sizeof(buf));
if(sret == 0){
break;
}
MD5_Update(&ctx, buf, sret);
}
unsigned char mdFromRecver[16]; // 将要保存md5码16个字节的二进
MD5_Final(mdFromRecver, &ctx);
// 写入文件表
int insRet = insertSql(train1.data, mysql, usr, newPath);
if(insRet == 0){
LOGRECORD(INFO,"insertSql success ");
}else{
LOGRECORD(INFO,"insertSql faild ! ");
}
LOGRECORD(INFO,"recvFile finish");
printf("此接收文件无错误\n");
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化