收发文件

循环接收

1
2
3
4
5
6
7
8
9
10
#include "Client.h"
int recvn(int sockfd, void *buf, int size){
int total = 0;
char *p = (char *)buf;
while(total < size){
ssize_t sret = recv(sockfd, p+total, size-total, 0);
total += sret;
}
return total;
}

收文件

根据对方发送的文件名,在当下实现文件的接收

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
int RecvFile(int sockfd){
FileBuf train;
char filename[128] = {0};
recv(sockfd, &train.size, sizeof(train.size), MSG_WAITALL);
recv(sockfd, train.buf, train.size, MSG_WAITALL);
memcpy(filename, train.buf, train.size);

int fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
//
off_t filesize;
recvn(sockfd, &train.size, sizeof(train.size));
recvn(sockfd, train.buf, train.size);
memcpy(&filesize, train.buf, train.size);
/* printf("filesize = %ld\n",filesize); */
off_t cursize = 0;
off_t lastsize = 0;
off_t slice = filesize/10000;
//
/* recv(netfd,&train.size,sizeof(train.buf),0);// */
while(1){
recvn(sockfd, &train.size, sizeof(train.size));
if(train.size == 0)
break;
cursize += train.size;
if(cursize - lastsize > slice){
printf("%5.2lf%%\r", 100.0 * cursize / filesize);
fflush(stdout);
lastsize = cursize;
}
recvn(sockfd, train.buf, train.size);
write(fd, train.buf, train.size);
}
printf("100.00%%\n");
close(fd);
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
int TransFile(int sockfd, char *pathname){
// word : 文件名
FileBuf train;
char *name = strtok(pathname, "/");
char *p = name;
while(p != NULL){
name = p;
p = strtok(NULL, "/");
}

char filename[128];
strcpy(filename, pathname);
train.size = strlen(filename);
memcpy(train.buf, filename, train.size);
send(sockfd, &train.size, sizeof(train.size),0);
send(sockfd, train.buf, train.size, 0);
//
int fd = open(pathname, O_RDWR);
if(fd == -1){
printf("%s is not existence!\n", filename);
return 0;
}
// 传入文件名
struct stat statbuf;
fstat(fd, &statbuf);
off_t filesize = statbuf.st_size;
train.size = sizeof(filesize);
memcpy(train.buf, &filesize, train.size);
send(sockfd, &train.size, sizeof(train.size), MSG_NOSIGNAL);
send(sockfd, train.buf, train.size, MSG_NOSIGNAL);

//
while(1){
bzero(train.buf, sizeof(train.buf));
ssize_t sret = read(fd, train.buf, sizeof(train.buf));
train.size = sret;
send(sockfd, &train.size, sizeof(train.size),0);
send(sockfd, train.buf, train.size,0);
if(sret == 0)
break;
}

close(fd);
return 0;
}

Makefile

1
2
3
4
5
6
7
8
9
10
11
clean: Client
rm -rf *.o
Client: Client.o Init.o Cmd.o File.o
gcc Client.o Init.o Cmd.o File.o -o Client -lpthread Client.o: Client.c
gcc -c Client.c -g -Wall -o Client.o
Init.o: Init.c
gcc -c Init.c -g -Wall -o Init.o
Cmd.o: Cmd.c
gcc -c Cmd.c -g -Wall -o Cmd.o
File.o: File.c
gcc -c File.c -g -Wall -o File.o

旧版可见:

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
#include "client.h"

int SockfdCreate(char *argv1,char* argv2){
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
ERROR_CHECK(sockfd, -1, "socket");
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv2));
serveraddr.sin_addr.s_addr = inet_addr(argv1);
int cret = connect(sockfd, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
ERROR_CHECK(cret, -1, "connect");
printf("Server has been connected\n");
return sockfd;
}
int EpollCreate(int sockfd){
int epfd = epoll_create(1);
ERROR_CHECK(epfd, -1, "epoll_create");
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = STDIN_FILENO;
event.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &event);
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);
return epfd;
}
int Command(char *cmd){
if (strcmp(cmd, "cd") == 0) {
return 0;
} else if (strcmp(cmd, "ls") == 0) {
return 1;
} else if (strcmp(cmd, "pwd") == 0) {
return 2;
} else if (strcmp(cmd, "puts") == 0) {
return 3;
} else if (strcmp(cmd, "gets") == 0) {
return 4;
} else if (strcmp(cmd, "remove") == 0) {
return 5;
} else if (strcmp(cmd, "mkdir") == 0) {
return 6;
} else if (strcmp(cmd, "rmdir") == 0) {
return 7;
} else {
return -1;
}
}
int main(int argc, char *argv[]){
//./client 127.0.0.1 1234
ARGS_CHECK(argc, 3);
int sockfd = SockfdCreate(argv[1], argv[2]);
int epfd = EpollCreate(sockfd);
struct epoll_event readyset[2];
char buf[1024];
Resource *res = (Resource *)malloc(sizeof(Resource));
pthread_mutex_init(&res->mutex, NULL);
pthread_cond_init(&res->cond, NULL);
while(1){
memset(buf, 0, sizeof(buf));
int readynum = epoll_wait(epfd, readyset, 2, -1);
for(int i = 0; i < readynum; ++i){
if(readyset[i].data.fd == sockfd){
//接收反馈
int ret = recv(sockfd, buf, sizeof(buf), 0);
if(ret <= 0){
printf("Server exit\n");
close(sockfd);
close(epfd);
return 0;
}
printf("%s\n", buf);
}else{
//发送信号
ssize_t ret = read(STDIN_FILENO, buf, sizeof(buf));
if(ret == 0){
close(sockfd);
close(epfd);
return 0;
}
res->sig = (SignalSend *)calloc(1, sizeof(SignalSend));
const char delim[] = "/";
res->sig->sig_t = Command(strtok(buf, " "));
if(res->sig->sig_t >=0 && res->sig->sig_t <=7){
do{
res->sig->pathname[res->sig->size] = strtok(NULL, delim); // 注意这里传递的是 NULL
++ res->sig->size;
}while (res->sig->pathname[res->sig->size] != NULL);
send(sockfd, res->sig, sizeof(SignalSend), 0);
if(res->sig->sig_t == 4 || res->sig->sig_t == 5){
//此处接发文件
//让线程
sleep(1);
}
free(res->sig);
}
printf("Error stdio\n");
}
}
}
close(sockfd);
close(epfd);
return 0;
}