1. server.c
(a)为了将传过来的文件保存为不同的文件内容,故用本机时间的十六进制作为文件名
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/stat.h> #include<fcntl.h> #include<time.h> #include<errno.h> #define oops(msg) { perror(msg); exit(errno); } int main(){ int sd = socket(PF_INET, SOCK_STREAM, 0); if(sd == -1) oops("socket"); struct sockaddr_in address; bzero((void *)&address, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("192.168.227.128"); address.sin_port = 8888; int bind_return = bind(sd, (struct sockaddr *)&address, sizeof(address)); if(bind_return == -1) oops("bind"); int listen_return = listen(sd, 1); if(listen_return == -1) oops("listen"); while(1){ int client_fd = accept(sd, NULL, NULL); if(client_fd == -1) oops("accept"); time_t current_time = time(NULL); char fileName[50]; sprintf(fileName, "/root/study/socket/%x", current_time); int fd = open(fileName, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); if(fd == -1) oops("open"); char buff[1024]; ssize_t length; while((length = recv(client_fd, buff, sizeof(buff), 0)) > 0){ write(fd, buff, length); } close(fd); } return EXIT_SUCCESS; }
2. client.c
(1) 通过sendfile进行内核空间向socket传文件,也就是所为的zero copy。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<sys/sendfile.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/stat.h> #include<fcntl.h> #include<errno.h> #define oops(msg) { perror(msg); exit(errno); } int main(int argc, char *argv[]){ if(argc != 2)oops("which file not specified?"); int sd = socket(PF_INET, SOCK_STREAM, 0); if(sd == -1) oops("socket"); struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr("192.168.227.128"); address.sin_port = 8888; int connect_ret = connect(sd, (struct sockaddr*)&address, sizeof(address)); if(connect_ret == -1) oops("connect"); int fd = open(argv[1], O_RDONLY); off_t offset = 0; struct stat fileStatus; int fstat_ret = fstat(fd, &fileStatus); if(fstat_ret == -1)oops("fstat"); ssize_t length = sendfile(sd, fd, &offset, fileStatus.st_size); if(length == -1) {oops("sendfile");} else fprintf(stdout, "%ld characters have been send to server.\n", length); close(fd); close(sd); return EXIT_SUCCESS; }