CD\LS命令

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
#include "Server.h"
// CD命令实现
int CmdCd(char *path, const int depth, FileBuf_t *msg, Node_t *p){
DIR *dir =opendir(path);
if(dir == NULL){
sprintf(msg->buf, "(error: %s)", strerror(errno));
return -1;
}else{
p->depth = depth;
char *help;
char *pathblock = strtok_r(path, " /", &help);
for(int i = 0; i < DEPTH; ++i){
memset(p->path[i], 0, strlen(p->path[i]));
if(i <= depth){
pathblock = strtok_r(NULL, " /", &help);
memcpy(p->path[i], pathblock, strlen(pathblock));
}
}
closedir(dir);
}
return 0;
}

// LS命令实现
int CmdLs(const char* path, FileBuf_t *msg){
DIR *dir = opendir(path);
if (dir== NULL){
return -1; // 打开目录失败
}

struct dirent *readret;
readret = readdir(dir);
if(readret == NULL){
return -1;
}

char result[LENGTH] = {0};
while ((readret = readdir(dir)) != NULL){
// 跳过.和..
if (strcmp(readret->d_name, ".") == 0 || strcmp(readret->d_name, "..") == 0){
continue;
}
// 添加到结果缓冲区
if(strlen(result) + strlen(readret->d_name) + 2 < LENGTH){
strncat(result, readret->d_name, strlen(readret->d_name));
strcat(result, " ");
}
}
memcpy(msg->buf, result, strlen(result));
closedir(dir);
return 0;
}

服务端上传下载

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;
}