2017-05-14 7 views
-3

Ich versuche, einen einfachen Proxy-Server zu implementieren und so weit so gut, ich habe es geschafft, die GET-Methode richtig zu tun, aber jetzt muss ich ein Caching für sie implementieren. Die Idee dahinter ist, dass wenn ich die folgenden Befehle:Proxy-Implementierung mit Caching-System

  • GET www.google.com
  • GET www.cplusplus.com
  • GET www.google.com

Die Zum zweiten Mal werde ich gebeten, die Informationen von Google zu bekommen, sollte es von meinem Caching-System sein. Ich habe nachgedacht und der beste Weg, dies zu tun, ist ein einfaches Ablagesystem zu implementieren, wo ich die in Dateien empfangenen Informationen speichern und sie dann lesen kann, wenn ich die Datei als existent empfinde. Das einzige Problem, das ich habe, ist, dass ich keine Dateien wie http://elf.cs.edu.ro/

erstellen kann. Hier ist mein Code, damit Sie verstehen, was ich tue.

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <errno.h> 

void error(char* msg) { 
    perror(msg); 
    exit(0); 
} 

int main(int argc,char* argv[]) { 

int count = 0; 
FILE *in; 
FILE *out; 
pid_t pid; 
struct sockaddr_in addr_in,cli_addr,serv_addr; 
struct hostent* host; 
int sockfd,newsockfd; 

if(argc<2) 
    error("./proxy <port_no>"); 

printf("\n*****WELCOME TO PROXY SERVER*****\n"); 

bzero((char*)&serv_addr,sizeof(serv_addr)); 
bzero((char*)&cli_addr, sizeof(cli_addr)); 

serv_addr.sin_family=AF_INET; 
serv_addr.sin_port=htons(atoi(argv[1])); 
serv_addr.sin_addr.s_addr=INADDR_ANY; 


sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
if(sockfd<0) 
    error("Problem in initializing socket"); 

if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0) 
    error("Error on binding"); 


listen(sockfd,50); 
int clilen=sizeof(cli_addr); 



startpoint: 

newsockfd=accept(sockfd,(struct sockaddr*)&cli_addr,&clilen); 

if(newsockfd<0) 
error("Problem in accepting connection"); 

pid=fork(); 
//printf("Pid is: %d\n", pid); 
if(pid==0) { 
    sites saves[10]; 
    int noOfSites = 0; 
    struct sockaddr_in host_addr; 
    int flag=0,newsockfd1,n,port=0,i,sockfd1; 
    char buffer[510],t1[300],t2[300],t3[10], aux[510]; 
    char* temp=NULL; 
    bzero((char*)buffer,500); 
    recv(newsockfd,buffer,sizeof(buffer),0); 
    //printf("%s\n",buffer); 
    sscanf(buffer,"%s %s %s",t1,t2,t3); 
    //printf("%s\n",buffer); 

    if (((strncmp(t1,"GET",3)==0))&&((strncmp(t3,"HTTP/1.0",8)==0)||(strncmp(t3,"HTTP/1.0",8)==0))&&(strncmp(t2,"http://",7)==0)) { 
     strcpy(t1,t2); 
     int saved = 0; 
     flag=0; 

     for(i=7;i<strlen(t2);i++) { 
      if(t2[i]==':') { 
       flag=1; 
       break; 
      } 
     } 
     // printf("The site to GET is : %s\n",t2); 
     temp=strtok(t2,"//"); 
     if (flag==0) { 
      port=80; 
      temp=strtok(NULL,"/"); 
     } 
     else { 
      temp=strtok(NULL,":"); 
     } 

     sprintf(t2,"%s",temp); 
     host=gethostbyname(t2); 

        int it; 
      for (it = 0; it < noOfSites; it++){ 
      printf("Site saved is: %s\n", saves[it].site); 
      if (strcmp(saves[it].site,t2) == 0){ 
       saved = 1; 
       out = fopen(t2, "r"); 
       printf("We have cache!\n"); 
      } 
     } 
     if(flag==1) { 
      temp=strtok(NULL,"/"); 
      port=atoi(temp); 
     } 


     strcat(t1,"^]"); 
     temp=strtok(t1,"//"); 
     temp=strtok(NULL,"/"); 
     if(temp!=NULL) 
      temp=strtok(NULL,"^]"); 


     bzero((char*)&host_addr,sizeof(host_addr)); 
     host_addr.sin_port=htons(port); 
     host_addr.sin_family=AF_INET; 
     bcopy((char*)host->h_addr,(char*)&host_addr.sin_addr.s_addr,host->h_length); 

     sockfd1=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
     newsockfd1=connect(sockfd1,(struct sockaddr*)&host_addr,sizeof(struct sockaddr)); 
     sprintf(buffer,"\nConnected to %s IP - %s\n",t2,inet_ntoa(host_addr.sin_addr)); 
     if(newsockfd1<0) 
      error("Error in connecting to remote server"); 

     bzero((char*)buffer,sizeof(buffer)); 
     if(temp!=NULL) 
      sprintf(buffer,"GET /%s %s\r\nHost: %s\r\nConnection: close\r\n\r\n",temp,t3,t2); 
     else 
      sprintf(buffer,"GET/%s\r\nHost: %s\r\nConnection: close\r\n\r\n",t3,t2); 




     if (saved == 1){ 
      printf("Are we ever here\n"); 
      n = send(sockfd1,buffer,strlen(buffer),0); 
      char * line = NULL; 
      size_t len = 0; 
      ssize_t read; 
      int count = 0; 
      if (n<0) 
       error("Error writing to socket"); 
      else { 
       while ((read = getline(&line, &len, out)) != -1) { 
        //printf("Retrieved line of length %zu :\n", read); 
        if (count > 0) 
         write(newsockfd,line,read); 
        if (strcmp(line,"\r\n") == 0) 
         count++; 
       } 
      } 
     } 

     if (saved == 0){ 
      //printf("We are only here\n"); 
      strcpy(saves[noOfSites].site,t2); 
      noOfSites++; 
      printf("The new site file is: %d\n", noOfSites); 


      in = fopen(t2,"w"); 
      n=send(sockfd1,buffer,strlen(buffer),0); 
      printf("I have opened for writing: %s\n\n\n\n\n\n",t2); 

      if(n<0) 
       error("Error writing to socket"); 
      else { 
       do { 
        memset(buffer, 0, sizeof(buffer)); 
        n=recv(sockfd1,buffer,sizeof(buffer),0); 
        fwrite(buffer, n, 1, stdout); 
        printf("\n"); 
        fwrite(buffer, n, 1, in); 
        if(!(n<=0)) 
         write(newsockfd,buffer,n); 
       } while(n>0); 
      } 
     } 
    } 
    else { 
     send(newsockfd,"400 : BAD REQUEST\nONLY HTTP REQUESTS ALLOWED",18,0); 
    } 
    close(sockfd1); 
    close(newsockfd); 
    close(sockfd); 
    fclose(in); 
    return 0; 
} 
else { 
    close(newsockfd); 
    goto startpoint; 
} 
return 0; 
} 

Kann mir bitte jemand in die richtige Richtung zeigen? Ich möchte nicht, dass jemand es für mich tut, nur ein paar Ideen, wie du es machen würdest, damit ich eine Chance habe. Vielen Dank für Ihre Zeit!

+1

Fragen zur Debugging-Hilfe ("** warum funktioniert dieser Code nicht? **") müssen das gewünschte Verhalten, ein spezifisches Problem oder einen Fehler und den ** kürzesten Code ** enthalten, um ihn in der Frage selbst zu reproduzieren . Fragen ohne eine klare Problemstellung sind für andere Leser nicht nützlich. Siehe: [Erstellen eines minimalen, vollständigen und überprüfbaren Beispiels.] (/ Help/mcve) –

Antwort

0

Sie suchen nach einem allgemeinen Schlüssel/Wert-Datenspeicher. Sie können entweder eine Hash-Tabelle im Speicher verwenden, eine einfache Datenbank wie gdbm verwenden oder eine komplexere Datenbank wie MongoDB auswählen.

0

Es tut mir aufrichtig leid, wenn ich auf dem Weg ein paar Fehler gemacht habe und keine guten Fragen stelle, aber ich habe es geschafft, dieses Problem selbst zu lösen. Das Problem, das ich hatte, war, dass, als ich versuchte, Dateien zu erstellen, wo ich meine Informationen von den Get-Befehlen speichern konnte, ich versuchte, Dateien mit Namen wie zu erstellen: http://something.com/ es würde mich nicht lassen wie das/ist beim Erstellen von Dateien verboten von C-Programmen (oder so habe ich verstanden). Meine Aufgabe war einfach, das/durch etwas anderes zu ersetzen (in meinem Fall _) und es hat alles gut geklappt. Danke, dass du es versuchst und es tut mir wirklich leid, wenn ich dich dazu gebracht habe, Zeit zu verlieren, während du versuchst zu verstehen, was ich gesagt habe.

Also genauer gesagt, was ich versuche zu tun ist, wenn ich ein Get-Kommando das zweite Mal bekomme (gleicher Befehl mit demselben Link) Ich würde die Informationen aus der Datei, die ich erstellt habe, zuerst bekommen Zeit habe ich den Befehl erhalten. Es sollte so aussehen:

  • GET www.something.com HTTP/1.0 -> Ich brauche eine Datei mit dem Namen „www.something.com“, speichern Sie alle Daten von der Website in dieser Datei erstellen und schließe sie dann und sende diese Information natürlich an den für die Kommunikation geöffneten Socket.
  • GET www.something.com HTTP/1.0 -> Ich muss die Datei öffnen, die mit dem vorherigen Befehl erstellt wurde, und die zu sendenden Informationen abrufen aus dieser Datei

WIEDER, Entschuldigung, wenn ich jemanden beunruhigt habe. Vielen Dank!