📄 ppppeer.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <errno.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/types.h> #include <sys/param.h> #include <sys/ioctl.h> #include <net/if.h> #include <net/if_arp.h> #define MAXINTERFACES 16 #define MAXLINE 8192#define LISTENQ 1024#define MAXQUERY 100#define FALSE 0#define TRUE 1typedef struct sockaddr SA;#define RIO_BUFSIZE 8192typedef struct { int rio_fd; /* descriptor for this internal buf */ int rio_cnt; /* unread bytes in internal buf */ char *rio_bufptr; /* next unread byte in internal buf */ char rio_buf[RIO_BUFSIZE]; /* internal buffer */} rio_t;/* deregister all the entry from indexing server */void deregister(char *host, int port); /* add entry to the indexing server */void add_entry(char *host, int port, char* title);/* add entry to the local file: peerlist */void add_myfile(char *title, char *filename);/* Get the local host IP address */char* getLocalIP();/* The Rio package - robust I/O functions */ssize_t rio_readn(int fd, void *usrbuf, size_t n);ssize_t rio_writen(int fd, void *usrbuf, size_t n);void rio_readinitb(rio_t *rp, int fd); ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n);ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen);char *localhost; // localhost IP addressint myport; // localhost p2p port numberchar** queryresult; // Store at most MAXQUERY query results from indexing serverint main(int argc, char** argv){ int clientfd, port, listenfd; char *host, buf[MAXLINE]; rio_t rio; FILE *filelist; char *prompt; char *token; int get; int querycount = 0; queryresult = (char **)malloc(sizeof(char *) * MAXQUERY); fd_set read_set, ready_set; // for select() if(argc != 4) { printf("usage: %s <server_name> <server_port_number> <p2p_port_number>\n", argv[0]); exit(1); } host = argv[1]; port = atoi(argv[2]); myport = atoi(argv[3]); filelist = fopen("./peerlist", "r"); if (filelist == NULL) { printf("Error:can't open the peerlist.\n"); exit(1); } /* Get the domain name of itself from peerlist*/ char *temp = getLocalIP(); localhost = (char *)malloc(strlen(temp)+1); strcpy(localhost,temp); /* Register the local file entries to the indexing server。 */ clientfd = open_clientfd(host, port); rio_readinitb(&rio, clientfd); rio_writen(clientfd, "REGISTER\n", 9); /* register the files one by one * The format store in the peerlist is like: A_NICE_DAY localhost:./a.cpp * A_NICE_DAY is the key words, including:a, nice, day * localhost is the domain name * ./a.cpp is the filename */ while (fgets(buf, MAXLINE, filelist) != NULL) { if ((token = strchr(buf, ':')) != NULL) { token[0] = ':'; token[1] = '\0'; strcat(buf, localhost); rio_writen(clientfd, buf, strlen(buf)); rio_writen(clientfd, ":", 1); rio_writen(clientfd, argv[3], strlen(argv[3])); rio_writen(clientfd, "\n", 1); } } rio_writen(clientfd, ".\n", 2); /* End register */ fclose(filelist); /* Get the success info from server */ while(rio_readlineb(&rio, buf, MAXLINE)) { if (strcmp(buf, "SUCCESS\n") == 0) break; } close(clientfd); printf("Register to the indexing server successfully.\n"); prompt = "PPP>"; get = FALSE; /* Prepare for the select() */ listenfd = open_listenfd(myport); FD_ZERO(&read_set); FD_SET(STDIN_FILENO, &read_set); FD_SET(listenfd, &read_set); printf("Welcome to the peer-to-peer client!\n"); printf("Please input the key words you want to search.\n"); printf("Then input 'GET index' to get the files you want.(index=0,1,2)\n"); printf("If you want more than one file,please input like ""GET 0 1 2"".\n"); printf("Finally, input quit or exit to leave.\n"); while (1) { printf("%s", prompt); fflush(stdout); ready_set = read_set; select(listenfd+1, &ready_set, NULL, NULL, NULL); // The standard input is ready. if (FD_ISSET(STDIN_FILENO, &ready_set)) { if(fgets(buf, MAXLINE, stdin) != NULL) { // GET Command if (!(strncmp("GET", buf, 3))) { if (!get) { printf("Sorry, please do the query first.\n"); } else { size_t n; char *filelist; char *y; char *savept; char *portstr; int index; int filefd; /* deal with GET 0 1 2 ...*/ filelist = (char *)malloc(strlen(buf)+1); strcpy(filelist, buf); // ignore "GET" if((y=(char *)strtok_r(filelist," \t",&savept))!=NULL) { filelist = savept; } while((y=(char *)strtok_r(filelist," \t",&savept))!=NULL) { filelist = savept; index = atoi(y); size_t n; char *token, *token1; /* * Get file keys, file host,file port from queryresult[x] * It is like: key_keys localhost 20002 */ token = strchr(queryresult[index], ':'); token[0] = '\0'; token++; token1 = strchr(token, ':'); token1[0] = '\0'; token1++; token1[strlen(token1)-1] = '\0'; if ((!strcmp(token,localhost))&&(atoi(token1)==myport)) { printf("Sorry.The file of the search result is "); printf("from yourself. It already exists. "); printf("You needn't download it.\n"); } else { // Connect to remote file server filefd = open_clientfd(token, atoi(token1)); rio_readinitb(&rio, filefd); char buffer1[MAXLINE]; char filename[MAXLINE]; // Send to server the file title rio_writen(filefd, queryresult[index], strlen(queryresult[index])); rio_writen(filefd,"\n",1); // Get the file name from server rio_readlineb(&rio, filename, MAXLINE); filename[strlen(filename)-1] = '\0'; int fd; if ((fd=creat(filename,0666)) < 0) { printf("Error:failed to create file %s\n", filename); close(filefd); continue; } // Get the file body from server and // write to the file newly created while(rio_readlineb(&rio, buffer1, MAXLINE)!=0) { if (!strcmp(buffer1,".\n")) break; write(fd, buffer1, strlen(buffer1)); fflush(stdout); } close(filefd); // Add file entry to the indexing server add_entry(host, port, queryresult[index]); // add file entry to local peerlist add_myfile(queryresult[index], filename); printf("%d) file:%s retrieved from remote server.\n", index, filename); fflush(stdout); } } get = FALSE; } } else if (!(strncmp("quit", buf, 4))) { deregister(host, port); printf("The program exits.\n"); exit(0); } else if (!(strncmp("exit", buf, 4))) { deregister(host, port); printf("The program exits.\n"); exit(0); } else { /* Do the query */ get = TRUE; /* Connect to the indexing server */ clientfd = open_clientfd(host, port); rio_readinitb(&rio, clientfd); rio_writen(clientfd, "QUERY\n", 6); rio_writen(clientfd, buf, strlen(buf)); rio_writen(clientfd, ".\n", 3); printf("Query matches the following:\n\n"); fflush(stdout); while(rio_readlineb(&rio, buf, MAXLINE)) { if (strcmp(buf, "QUERY\n") == 0) { continue; } if (strcmp(buf, "SUCCESS\n") == 0) { printf("\nWhich one do you wish to download?\n"); fflush(stdout); break; } if (strcmp(buf, "FAILED\n") == 0) { printf("\nSorry, No file matches your key words.\n"); fflush(stdout); get = FALSE; break; } else { int k; int theSame = FALSE; for (k = 0; k < querycount; k++) { if (!strcmp(queryresult[k], buf)) { theSame = TRUE; } } if (!theSame) { // Store the query result for GET command queryresult[querycount] = (char *)malloc(strlen(buf)+1); strcpy(queryresult[querycount], buf); printf("%d) %s", querycount, queryresult[querycount]); fflush(stdout); querycount++; } } } querycount = 0; close(clientfd); } } } /* The socket is ready */ if (FD_ISSET(listenfd, &ready_set)) { int clientlen, connfd; struct sockaddr_in clientaddr; int i; clientlen = sizeof(clientaddr); connfd = accept(listenfd, (SA *)&clientaddr, &clientlen); printf("A client wants to download files from me.\n"); fflush(stdout); size_t n; char buffer[MAXLINE],buffer1[MAXLINE]; rio_t rio0,rio1; int j; int srcfd; char* filebuffer; struct stat sbuf; char holdbuffer[MAXLINE];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -