服务器server.c:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<string.h> #include<dirent.h> #include<fcntl.h> #include<errno.h> #define errlog(errmsg) do{\ perror(errmsg);\ exit(-1);\ }while(0) #define N 32 void do_list(int acceptfd); void do_get(int acceptfd,char *filename); void do_put(int acceptfd,char *filename); int main(int argc, const char *argv[]) { int sockfd,acceptfd; struct sockaddr_in serveraddr,clientaddr; socklen_t addrlen = sizeof(serveraddr); char buf[N] = {}; int ret; serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(atoi(argv[2])); serveraddr.sin_addr.s_addr = inet_addr(argv[1]); if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { errlog("fail to socket"); } if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0) { errlog("fail to bind"); } if(listen(sockfd,5) < 0) { errlog("fail to listen"); } while(1) { if((acceptfd = accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen)) < 0) { errlog("fail to accept"); } ret = recv(acceptfd,buf,N,0); if(ret < 0) { errlog("fail to recv"); }else if(ret == 0) { puts("%s:%d is disconnected"); continue; } switch(buf[0]) { case 'l': do_list(acceptfd); break; case 'g': do_get(acceptfd,buf + 4); break; case 'p': do_put(acceptfd,buf+4); break; default: puts("error cmd"); break; } close(acceptfd); } return 0; } void do_list(int acceptfd) { DIR *dp; struct dirent *dir; dp = opendir("."); if(dp == NULL) { errlog("fail to opendir"); } while(1) { dir = readdir(dp); if(dir == NULL) { break; } if(strncmp(dir->d_name,".",1) == 0) { continue; } send(acceptfd,dir->d_name,N,0); } } void do_get(int acceptfd,char *filename) { int fd; char buf[N] = {}; int ret; fd = open(filename,O_RDONLY); if(fd < 0) { if(errno == ENOENT) { buf[0] = 'N'; send(acceptfd,buf,N,0); return; }else{ errlog("fail to open"); } }else{ buf[0] = 'Y'; send(acceptfd,buf,N,0); } while(1) { ret = read(fd,buf,N); if(ret < 0) { errlog("fail to read"); }else if(ret == 0) { break; }else{ send(acceptfd,buf,ret,0); } } } void do_put(int acceptfd,char *filename) { int ret; char buf[N] = {}; int fd; fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666); //creat file if(fd < 0) { errlog("fail to open"); } while(1) { ret = recv(acceptfd,buf,N,0); //recv file if(ret < 0) { errlog("fail to upload"); }else if(ret == 0) { puts("upload sucess!"); break; }else{ write(fd,buf,ret); } } }
客户端client.c:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<string.h> #include<dirent.h> #include<fcntl.h> #include<errno.h> #define errlog(errmsg) do{\ perror(errmsg);\ exit(-1);\ }while(0) #define N 32 int start_up(struct sockaddr_in serveraddr); void do_list(struct sockaddr_in serveraddr); void do_get(struct sockaddr_in serveraddr,char *filename); void do_put(struct sockaddr_in serveraddr,char *filename); int main(int argc, const char *argv[]) { char buf[N] = {}; int ret; struct sockaddr_in serveraddr; serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(atoi(argv[2])); serveraddr.sin_addr.s_addr = inet_addr(argv[1]); while(1) { puts("****************************"); puts("* list * "); puts("* get filename * "); puts("* put filename * "); puts("****************************"); printf("input:"); fgets(buf,N,stdin); buf[strlen(buf) - 1] = '\0'; if(strncmp(buf,"list",4) !=0 && strncmp(buf,"get ",4) !=0 && strncmp(buf,"put ",4) != 0) { puts("error cmd"); continue; } printf("filename : %s\n",buf + 4); switch(buf[0]) { case 'l': do_list(serveraddr); break; case 'g': do_get(serveraddr,buf + 4); break; case 'p': do_put(serveraddr, buf + 4); break; default: puts("error cmd"); break; } } return 0; } int start_up(struct sockaddr_in serveraddr) { int sockfd; socklen_t addrlen = sizeof(serveraddr); sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd < 0) { errlog("fail to sockfd"); } if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0) { errlog("fail to connect"); } return sockfd; } void do_list(struct sockaddr_in serveraddr) { int sockfd = start_up(serveraddr); int ret; char buf[N] = {}; strcpy(buf,"list"); send(sockfd,buf,N,0); while(1) { ret = recv(sockfd,buf,N,0); if(ret < 0) { errlog("fail to recv"); }else if(ret == 0) { puts("LIST OVER"); break; }else{ printf("%s\n",buf); } } } void do_get(struct sockaddr_in serveraddr,char *filename) { int sockfd = start_up(serveraddr); int ret; char buf[N] = {}; int fd; strcat(strcpy(buf,"get "),filename); send(sockfd,buf,N,0); ret = recv(sockfd,buf,N,0); if(ret < 0) { errlog("fail to recv"); }else if(ret == 0) { puts("the server is shutdown"); exit(1); }else{ if(strncmp(buf,"N",1) == 0) { printf("%s does not exist\n",filename); return; } fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666); if(fd < 0) { errlog("fail to open"); } while(1) { ret = recv(sockfd,buf,N,0); if(ret < 0) { errlog("fail to recv"); }else if(ret == 0) { puts("GET OVER"); break; }else{ write(fd,buf,ret); } } } } void do_put(struct sockaddr_in serveraddr,char *filename) { int fd; char buf[N]={}; int ret; int sockfd = start_up(serveraddr); fd = open(filename,O_RDONLY); if(fd < 0) { if(errno == ENOENT) { printf("%s does not exist\n",filename); return; } else{ errlog("fail to open"); } }else { strcat(strcpy(buf,"put "),filename); send(sockfd,buf,N,0); strcpy(buf,filename); send(sockfd,buf,N,0); while(1) { ret = read(fd,buf,N); if(ret < 0) { errlog("fail to read"); }else if(ret == 0) { puts("upload OVER"); break; }else{ send(sockfd,buf,ret,0); } } } }