加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
puts.c 4.69 KB
一键复制 编辑 原始数据 按行查看 历史
SpaceX_zhao 提交于 2023-05-18 23:01 . alopex modify
#include "head.h"
// 文件大小少于 100MB 时,使用小文件传输
void transMinFile(int netfd, int fd){
printf("小文件发送\n");
train_t train;
while(1){
bzero(&train, sizeof(train));
ssize_t sret = read(fd, train.data, sizeof(train.data));
if(sret == 0){
break;
}
train.length = sret;
sret = send(netfd, &train, sizeof(train.length)+train.length, MSG_NOSIGNAL);
}
// 发送空车箱
train.length = 0;
send(netfd, &train, sizeof(train.length), MSG_NOSIGNAL);
}
// 大文件的发送,mmap方式
void transMaxFile(int netfd, int fd, off_t fileSize){
printf("大文件发送\n");
char *p = (char *)mmap(NULL, fileSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ERROR_CHECK(p, MAP_FAILED, "mmap");
send(netfd, p, fileSize, MSG_NOSIGNAL);
munmap(p, fileSize);
}
// 续传的发送
void transAgain(int netfd, int fd, off_t fileSize, off_t offset){
printf("续传发送\n");
// 使用mmap
char *p = (char *)mmap(NULL, fileSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
ERROR_CHECK(p, MAP_FAILED, "mmap");
send(netfd, p+offset, fileSize-offset, MSG_NOSIGNAL);
munmap(p, fileSize);
}
int getPath(char* path,int currid, MYSQL* mysql){
LOGRECORD(INFO,"getPath start");
char sqlCommand[1024];
bzero(sqlCommand,sizeof(sqlCommand));
sprintf(sqlCommand,"select path from vfsystem where id = %d",currid);
int ret = mysql_query(mysql, sqlCommand);
if(ret != 0){
LOGRECORD(ERROR,"mysql_query");
return -1;
}
MYSQL_RES *result = mysql_store_result(mysql);
MYSQL_ROW row = mysql_fetch_row(result);
if(row == NULL){
LOGRECORD(ERROR,"mysql_fetch_row");
return -1;
}else{
strcpy(path,row[0]);
}
return 0;
}
int sendFile(int netfd, const char *fileName, MYSQL* mysql, userProcess_t* usr){
char sqlCommand[1024];
bzero(sqlCommand,sizeof(sqlCommand));
char path[128];
bzero(path, sizeof(path));
getPath(path, usr->curid, mysql);
LOGRECORD(INFO,"getPath finish");
printf("%s %d %s\n",usr->username,usr->curid,fileName);
sprintf(sqlCommand, "select MD5 from vfsystem "
"where user = '%s' and tomb = 0 and name = '%s'",
usr->username, fileName);
int ret = mysql_query(mysql, sqlCommand);
ERROR_CHECK(ret, -1, "mysql_query");
MYSQL_RES *result = mysql_store_result(mysql);
MYSQL_ROW row = mysql_fetch_row(result);
if(row == 0){
LOGRECORD(ERROR,"MD5 IS NOT EXISTS");
return -1;
}
char realfile[128] = {0};
strcpy(realfile,row[0]);
LOGRECORD(INFO,"sendfile start");
train_t train1, train2, train3, train4;
// step1:发送文件名的长度和文件名
bzero(&train1, sizeof(train1));
train1.length = strlen(fileName);
memcpy(train1.data, fileName, train1.length);
send(netfd, &train1, sizeof(train1.length)+train1.length, MSG_NOSIGNAL);
// step2:发送文件的总大小
int fd = open(realfile, O_RDWR);
ERROR_CHECK(fd, -1, "open");
bzero(&train2, sizeof(train2));
struct stat statbuf;
fstat(fd, &statbuf);
off_t fileSize = statbuf.st_size;
printf("fileSize = %ld\n", fileSize);
train2.length = sizeof(statbuf.st_size);
memcpy(train2.data, &statbuf.st_size, train2.length);
send(netfd, &train2, sizeof(train2.length)+train2.length, MSG_NOSIGNAL);
// step3:发送文件的md5码
LOGRECORD(INFO,"start to send MD5");
bzero(&train3,sizeof(train3));
train3.length = strlen(realfile);
strcpy(train3.data,realfile);
send(netfd, &train3, sizeof(train3.length)+train3.length, MSG_NOSIGNAL);
printf("send md5 done!\n");
// 偏移到文件开头
lseek(fd, 0, SEEK_SET);
// step4:接收偏移量(接收放已接收的文件大小)
bzero(&train4, sizeof(train4));
off_t offset;
recvn(netfd, &train4.length, sizeof(train4.length));
recvn(netfd, train4.data, train4.length);
if(train4.length == 0){
recvn(netfd, &train4.length, sizeof(train4.length));
recvn(netfd, train4.data, train4.length);
}
memcpy(&offset, train4.data, sizeof(off_t));
printf("offset = %ld\n", offset);
if(offset == fileSize){
printf("秒传模式\n");
}
else{
if(offset > 0){
// 续传
transAgain(netfd, fd, fileSize, offset);
}
else if(offset == 0 && fileSize >= 100*1024*1024){
// 大文件发送
transMaxFile(netfd, fd, fileSize);
}
else if(offset == 0 && fileSize < 100*1024*1024){
// 小文件发送
transMinFile(netfd, fd);
}
}
printf("send file done!\n");
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化