myserver.c
来自「windows与linux间的文件转输」· C语言 代码 · 共 307 行
C
307 行
/* myclient.c* files thrans server*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <pthread.h>#include <sys/socket.h>#include <sys/types.h>#include <dirent.h>#include <netinet/in.h>#include <netdb.h>#include <error.h>#define MAX_FILENAME 32#define BUFSIZE 256#define BACKLOG 10typedef struct _fileinfo { char type; //type:list dir,download or upload unsigned short number; //witch part of the file char filename[MAX_FILENAME]; //file name include path unsigned position; //read or write begin position unsigned sendsize; //the part size}fileinfo;//thread function declarationvoid * sockthread(void *arg);//main functionint main(int argc, char *argv[]) { //enter port number after program's name if(argc != 2) { perror("enter port number"); exit(1); } //init socket int portnumber = atoi(argv[1]); int sockfd, client_fd; struct sockaddr_in serv_sockaddr; struct sockaddr_in client_sockaddr; int sin_size,recvbytes,sendbytes; char c, buf[BUFSIZE]; if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) { perror("socket faild"); exit(1); } printf("socket success! sockfd: %d\n",sockfd); bzero(&serv_sockaddr.sin_zero,0); serv_sockaddr.sin_family = AF_INET; serv_sockaddr.sin_addr.s_addr = INADDR_ANY; serv_sockaddr.sin_port = htons(portnumber); //bind socket if(bind(sockfd,(struct sockaddr *)&serv_sockaddr,sizeof(struct sockaddr)) == -1) { perror("bind faild!"); exit(1); } printf("bind success.\n"); //listen socket if(listen(sockfd,BACKLOG) == -1) { perror("listen faild!"); exit(1); } printf("listening ...\n"); //if have connect creat thread to process while (1) { int *new_fd = (int *)malloc(sizeof(int)); pthread_t pid; //accept socket if((*new_fd = accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size)) == -1) { perror("accept faild!"); exit(1); } //thread create if(pthread_create(&pid,NULL,sockthread,(void *)new_fd)) { perror("thread cread faild."); exit(1); } } exit(0);}// function declarationvoid processlist(char *in_buf,int new_fd);void processdownload(char *in_buf, int new_fd);void processupload(char *in_buf, int new_fd);//socket thread function void * sockthread(void *arg) { int new_fd = *(int *)arg; int recvbytes; char buf[BUFSIZE]; printf("this is sockthread.sock:%d\n",new_fd); //recv data if((recvbytes = recv(new_fd,buf,BUFSIZE,0)) == -1) { perror("recv faild."); exit(1); } printf("recv %d bytes\n",recvbytes); //check the fist byte if(buf[0] == 'l') processlist(buf,new_fd); if(buf[0] == 'r') processdownload(buf,new_fd); if(buf[0] == 'w') processupload(buf,new_fd); free(arg); //free the malloc in the main function pthread_exit((void*)new_fd);}//function to process upload from clientvoid processupload(char *in_buf, int new_fd) { FILE *fd; int recvbytes, sendbytes,writebytes; int totalbytes = 0; char buf[BUFSIZE]; fileinfo *fip = (fileinfo *)in_buf; //init fileinfo fileinfo fi; fi.type = fip->type; fi.number = fip->number; strcpy(fi.filename,fip->filename); fi.position = fip->position; fi.sendsize = fip->sendsize; totalbytes = fi.sendsize; //send message to client printf("filename :%s\n",fi.filename); if((sendbytes = send(new_fd,fi.filename,MAX_FILENAME,0)) == -1) { perror("send faild."); exit(1); } printf("send %d bytes\n",sendbytes); //if open file success fseek to the postion if((fd = fopen(fi.filename,"wb")) != NULL) { if(fseek(fd,fi.position,SEEK_SET)) { perror("fseek error."); exit(1); } printf("open file OK.\n"); //recv file data and write to file while((recvbytes = recv(new_fd,buf,BUFSIZE,0)) > 0 && totalbytes > 0) { if((writebytes = fwrite(buf,sizeof(char),recvbytes,fd)) < 0) { perror("write faild"); exit(1); } totalbytes -= writebytes; // printf("writebytes: %d\n",writebytes); } if(recvbytes == -1) { perror("recvbytes error."); exit(1); } //check if(totalbytes != 0) { printf("sendbytes error\n"); } else printf("send finish\n"); } fclose(fd); }//list dir to clientvoid processlist(char *in_buf,int new_fd) { printf("this is processlist\n"); char buf[BUFSIZE]; int strsize; DIR *dp; struct dirent *dirp; struct stat filestat; in_buf++; //find dir name from client char *dirname = in_buf; bzero(buf,BUFSIZE); if((dp = opendir(dirname)) == NULL) { perror("open dir faild."); exit(1); } strsize = BUFSIZE; while((dirp = readdir(dp)) != NULL) { if(strcmp(".",dirp->d_name) == 0 ||strcmp("..",dirp->d_name) == 0) continue; stat(dirp->d_name,&filestat); char size[9]; sprintf(size,"%d",filestat.st_size); strcat(buf,size); strsize -= 9; strcat(buf,"\t"); strsize -= 2; strcat(buf,dirp->d_name); //printf("%s\n",dirp->d_name); strsize -= strlen(dirp->d_name); strcat(buf,"\n"); strsize -= 2; if(strsize < MAX_FILENAME + 13) { if(send(new_fd,buf,BUFSIZE,0) == -1) { perror("send faild in processlist"); pthread_exit((void*)new_fd); } bzero(buf,BUFSIZE); strsize = BUFSIZE; } } if(send(new_fd,buf,BUFSIZE,0) == -1) { perror("send faild in processlist"); pthread_exit((void*)new_fd); } close(new_fd); }//function to process download from clientvoid processdownload(char *in_buf, int new_fd) { printf("this is process download.\n"); FILE *fd; int recvbytes, sendbytes,readbytes, writebytes; int totalbytes = 0; char buf[BUFSIZE]; fileinfo *fip = (fileinfo *)in_buf; //init fileinfo fileinfo fi; fi.type = fip->type; fi.number = fip->number; strcpy(fi.filename,fip->filename); fi.position = fip->position; fi.sendsize = fip->sendsize; totalbytes = fi.sendsize;/* //send message to client printf("filename :%s\n",fi.filename); if((sendbytes = send(new_fd,fi.filename,MAX_FILENAME,0)) == -1) { perror("send faild."); exit(1); } printf("send %d bytes\n",sendbytes);*/ //if open file success fseek to the postion if((fd = fopen(fi.filename,"rb")) == NULL) { perror("fopen faild in download."); exit(1); } if(fseek(fd,fi.position,SEEK_SET)) { perror("fseek error."); exit(1); } printf("open file %s OK in download.\n",fi.filename); //read file data and send to client readbytes = BUFSIZE; while( totalbytes > 0) { if(totalbytes < BUFSIZE) readbytes = totalbytes; if((readbytes = fread(buf,sizeof(char),readbytes,fd)) < 0) { perror("read faild"); exit(1); } printf("fread ok\n"); if((sendbytes = send(new_fd,buf,readbytes,0)) < 0) { perror("send data to client faild."); exit(1); } printf("send ok\n"); totalbytes -= sendbytes; printf("filenumber: %d to %d\n",fi.number,fi.position + fi.sendsize - totalbytes); } //check if(totalbytes != 0) { printf("sendbytes error\n"); } else printf("send finish\n"); close(new_fd); fclose(fd); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?