⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppppeer.c

📁 A peer-to-peer file sharing system under UNIX environment.
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -