2017-05-14 15 views
-3

シンプルなプロキシサーバーを実装しようとしていますが、これまでのところGETメソッドを正しく処理できましたが、今はキャッシングを実装する必要があります。その背後にある考え方は、私は次のコマンドを取得するときにということで:キャッシングシステムを使用したプロキシの実装

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

2回目は私のキャッシュシステムからGoogleの情報を取得するよう求められます。私は考えてきました。これを行う最善の方法は、受信した情報をファイルに保存し、ファイルが存在する場合はいつでもそれを読み取るシンプルなファイリングシステムを実装することです。私が抱いている唯一の問題は、ファイルを作成できないということです。http://elf.cs.edu.ro/

ここに私のコードがありますので、私が何をしているのか分かります。

#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; 
} 

誰でも正しい方向に向けることができますか?私は誰かが私のためにそれをするのを望んでいない、ちょうどあなたがそれをやる方法についてのちょっとしたアイデアなので、チャンスがあるかもしれない。あなたの時間をありがとう!

+1

デバッグヘルプ( "**なぜこのコードは機能していないのですか?**")は、質問自体に再現するために、必要な動作、特定の問題またはエラー、および**最短のコードが必要です。明確な問題文がない質問は、他の読者にとって有用ではありません。参照:[最小限で完全で検証可能な例の作成方法](/ help/mcve) –

答えて

0

一般的なキー/値データストアを探しています。メモリにハッシュテーブルを使用するか、gdbmのような単純なデータベースを使うか、MongoDBのようなより高度なデータベースを選ぶことができます。

0

途中で間違いを犯しても良い質問を投稿していないのであれば、本当に申し訳ありませんが、私は自分自身でこれを理解することができました。私が抱えていた問題は、getコマンドから自分の情報を保存する場所にファイルを作成しようとしたときに、ファイル名をつけてファイルを作成しようとしていたことです。http://something.com/ファイルを作成しようとすると/が禁止されますCのプログラムから(または私が理解している)。私の仕事はシンプルで、/を何か他のもの(私の場合_)に置き換えれば、すべてうまくいった。試していただきありがとうございます、私はあなたが私が言っていることを理解しようとしている間に時間を失うようにした場合、本当にすみません。

もっと正確に言えば、私がやろうとしているのは、2回目のgetコマンド(同じリンクで同じgetコマンド)を受け取ったときです。最初に作成したファイルから情報を取得する必要があります私はコマンドを受け取った。

  • GET www.something.com HTTP/1.0 - >「www.something.com」という名前のファイルを作成し、サイトのすべての情報をそのファイルに保存する必要がありますそれを閉じて、もちろんその情報を通信のために開いたソケットに送信してください。
  • GET www.something.com HTTP/1.0 - >私は前のコマンドで作成したファイルを開き、送信する情報を取得する必要がありますそのファイルから

私は誰かに悩まされている場合はごめんなさい。どうもありがとうございました!

関連する問題