1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
| #include "Server.h"
int RecvFile(int sockfd){ int judge; //1.接收文件状态判断 if(recv(sockfd, &judge, sizeof(int), 0) != sizeof(int)){ return -1; } if(judge == -1){ return -1; } //2.接收文件大小,文件名 FileBuf_t filemsg; if(recv(sockfd, &filemsg, sizeof(FileBuf_t), MSG_WAITALL) != sizeof(FileBuf_t)){ return -1; } int filesize = filemsg.size; //文件尺寸 int fd = open(filemsg.buf, O_RDWR|O_CREAT, 0666); if(fd == -1){ return -1; }
//3.告知偏移尺寸 struct stat file; fstat(fd, &file); int offsize = file.st_size; //告知本地文件大小 send(sockfd, &offsize, sizeof(int), 0);
off_t remaining = filesize - offsize; ftruncate(fd, filesize); char *addr = (char *)mmap(NULL, remaining, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offsize); char *mmap_addr = addr; if(mmap_addr == NULL){ close(fd); return -1; }
while(offsize < filesize){ size_t recvnum = filesize - offsize; if(recvnum > 2 * LENGTH){ recvnum = 2 * LENGTH; } //4.发送信息 int ret = recv(sockfd, mmap_addr + offsize, recvnum, 0); if(ret <= 0){ munmap(mmap_addr, remaining); // 释放映射 close(fd); return -1; } offsize += ret; // 累计已发送字节 if(filesize > 100 * 1024 * 1024){ double percent = (double)offsize / filemsg.size * 100; printf("\r进度: %.2lf%%", percent); fflush(stdout); } } printf("文件下载完成,总大小:%ld bytes\n", (long)filesize); munmap(mmap_addr, remaining); // 释放映射 //while(offsize < filesize){ // //清空数据 // bzero(filemsg.buf, sizeof(filemsg.buf)); // //读数据
// if(recv(sockfd, &filemsg.size, sizeof(int), 0) < 0){ // close(fd); // return -1; // } // off_t offsize = 0; // while(offsize < filemsg.size){ // int ret = recv(sockfd, filemsg.buf, filemsg.size - offsize, 0); // if(ret < 0){ // close(fd); // return -1; // } // write(fd, filemsg.buf, ret); // offsize += ret; // } // offsize += filemsg.size; //}
close(fd); return 0; } int TransFile(int sockfd, char *pathname){ // 1.上传文件名并判断是否有这个文件 int fd = open(pathname, O_RDONLY); int judge = fd; send(sockfd, &judge, sizeof(int), 0); if(fd == -1){ return -1; }
struct stat file; fstat(fd, &file);
//获得文件名与大小,实现断点重传 FileBuf_t filemsg; filemsg.size = file.st_size; char *filename = strtok(pathname, " /"); strncpy(filemsg.buf, filename, strlen(filename)); while(filename != NULL){ strncpy(filemsg.buf, filename, strlen(filename)); filename = strtok(NULL, " /"); }
//2.发送文件尺寸和文件名 //3.接收偏移尺寸 off_t offsize; if(send(sockfd, &filemsg, sizeof(FileBuf_t), 0) <= 0 || recv(sockfd, &offsize, sizeof(int), 0) <= 0){ close(fd); return -1; } lseek(fd, offsize, SEEK_SET);
off_t remaining = file.st_size - offsize; // 剩余需传输的大小 if(file.st_size > 100 * 1024 *1024){ void *mmap_addr = mmap(NULL, remaining, PROT_READ, MAP_SHARED, fd, offsize); if(mmap_addr == NULL){ close(fd); return -1; }
char *data_ptr = (char *)mmap_addr; while(offsize < file.st_size){ size_t sendnum = file.st_size - offsize; if(sendnum > 2 * LENGTH){ sendnum = 2 * LENGTH; } //4.发送信息 int ret = send(sockfd, data_ptr + offsize, sendnum, MSG_NOSIGNAL); if(ret < 0){ munmap(mmap_addr, remaining); // 释放映射 close(fd); return -1; } offsize += ret; // 累计已发送字节 double percent = (double)offsize / filemsg.size * 100; printf("\r进度: %.2lf%%", percent); fflush(stdout); }
munmap(mmap_addr, remaining); }else{ while(offsize < file.st_size){ bzero(filemsg.buf, sizeof(filemsg.buf)); filemsg.size = read(fd, filemsg.buf, sizeof(filemsg.buf)); if(filemsg.size < 0){ break; }
int sendnum = 0; //4.发送信息 while(sendnum < filemsg.size){ int ret = send(sockfd, filemsg.buf, filemsg.size - sendnum, MSG_NOSIGNAL); if(ret <= 0){ close(fd); return -1; } sendnum += ret; } offsize += filemsg.size; } } close(fd); printf("文件传输完成,总大小:%ld bytes\n", (long)file.st_size); return 0; }
|