Frage

Ich versuche, einen kleinen Web -Proxy in C zu erstellen. Zuerst versuche ich, eine Webseite zu erhalten und einen Get -Frame an den Server zu senden. Ich weiß nicht, was ich verpasst habe, aber ich erhalte keine Antwort. Ich würde mich sehr freuen, wenn Sie mir helfen können, herauszufinden, was in diesem Code fehlt.

int main (int argc, char** argv) {
   int cache_size,     //size of the cache in KiB
       port,
       port_google = 80,
       dir,
       mySocket,
       socket_google;

   char google[] = "www.google.es", ip[16];
   struct sockaddr_in socketAddr;
   char buffer[10000000];

   if (GetParameters(argc,argv,&cache_size,&port) != 0)
       return -1;

   GetIP (google, ip);
   printf("ip2 = %s\n",ip);

   dir = inet_addr (ip);
   printf("ip3 = %i\n",dir);

   /* Creation of a socket with Google */
   socket_google = conectClient (port_google, dir, &socketAddr);
   if (socket_google < 0) return -1;
   else printf("Socket created\n");

   sprintf(buffer,"GET /index.html HTTP/1.1\r\n\r\n");
   if (write(socket_google, (void*)buffer, MESSAGE_LENGTH+1) < 0 )
       return 1;
   else printf("GET frame sent\n");

   strcpy(buffer,"\n");
   read(socket_google, buffer, sizeof(buffer));

   // strcpy(message,buffer);
   printf("%s\n", buffer);

   return 0;
}

Und dies ist der Code, den ich zum Erstellen der Socket verwende. Ich denke, dieser Teil ist in Ordnung, aber ich kopiere ihn nur für den Fall.

int conectClient (int puerto, int direccion, struct sockaddr_in *socketAddr) {
   int mySocket;
   char error[1000];

   if ( (mySocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
       printf("Error when creating the socket\n");
       return -2;
   }

   socketAddr->sin_family = AF_INET;
   socketAddr->sin_addr.s_addr = direccion;
   socketAddr->sin_port = htons(puerto);

   if (connect (mySocket, (struct sockaddr *)socketAddr,sizeof (*socketAddr)) == -1) {
       snprintf(error, sizeof(error), "Error in %s:%d\n", __FILE__, __LINE__);
       perror(error);
       printf("%s\n",error);
       printf ("-- Error when stablishing a connection\n");
       return -1;
   }
   return mySocket;
}

Vielen Dank!

War es hilfreich?

Lösung

Da du das nicht gepostet hast GetIP Routine bin ich nicht sicher, ob Ihre Hostname -Suche korrekt ist, wie aus dem Aussehen, ich bin mir nicht sicher, ob Sie es verwenden inet_addr korrekt funktionieren.

Nikolai hat auf einige sehr gute Punkte hingewiesen (und ich stimme voll und ganz zu). In der Tat du GET Die Anfrage ist tatsächlich gebrochen, und während ich sie auf meinem eigenen lokalen Apache -Webserver auf meinem System getestet habe, hat es nicht funktioniert.

sprintf(buffer,"GET /index.html HTTP/1.1\r\n\r\n");
if (write(socket_google, (void*)buffer, LONGITUD_MSJ+1) < 0 )
    return 1;
else printf("GET frame sent\n");
...

strcpy(buffer,"\n");
read(socket_google, buffer, sizeof(buffer));

sollte durch ersetzt werden durch

  snprintf(buffer, sizeof(buffer), 
      "GET / HTTP/1.1\r\nHost: %s\r\nUser-Agent: TEST 0.1\r\n\r\n", 
      google);

  if (write(socket_google, buffer, strlen(buffer)+1) < 0 ) {
      close(socket_google);
      return 1;
  } else 
      printf("GET frame sent\n");
  ...

  buffer[0] = '\0';
  /* Read message from socket */
  bytes_recv = read(socket_google, buffer, sizeof(buffer));
  if (bytes_recv < 0) {
       fprintf(stderr, "socket read error: %s\n", strerror(errno));
       close(socket_google);
       exit(10);
  }

  buffer[bytes_recv] = '\0';    /* NUL character */

  /* strcpy(message,buffer); */
  printf("%s\n", buffer);

  ...

Du solltest auch close die Steckdose vor dem Verlassen des Programms. Aktivieren Sie den Standard -C89/90- oder C99 -Modus Ihres Compilers (z. -std=c99 für GCC) und Warnungen aktivieren (z. B. -Wall für GCC) und lesen Sie sie. Und #include Die erforderlichen Header -Dateien (unter der Annahme von Linux in meinem Fall) für Funktionsprototypen:

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

Es gibt einige Casting von Zeigern und structs in Bezug auf die Auflösung des Hostnamens / der IP -Adresse, die verwirrend und einfach sein kann, um einen Fehler zu machen. Stellen Sie also sicher, dass dies so funktioniert, wie Sie es erwarten.

 in_addr_t ip;
 ...

 GetIP(google, &ip);   /* I changed the parameters */
 printf("IP address = %x (%s)\n", 
     ip, 
     inet_ntoa(*((struct in_addr*)&ip)));

Andere Tipps

Erstens überprüfen Sie nicht, wie viele Bytes die write(2) Rufen Sie tatsächlich an den Socket geschrieben. Der Rückgabewert des Anrufs sagt Ihnen das. Gleiches gilt für die read(2). Die TCP-Socket ist ein bidirektionaler Strom, so dass in der Regel immer beides in einer Schleife möglich ist, bis die erwartete Anzahl von Bytes übertragen wird. EOF wird gelesen (Zero Return von read(2)) oder ein Fehler aufgetreten (nach dem Sie auch beim Lesen nicht überprüfen).

Dann ist HTTP ein ziemlich komplexes Protokoll. Sich vertraut machen mit RFC 2616, insbesondere Anwendungsstufeverbindungsmanagement- und Übertragungscodierungen.

Bearbeiten 0:

Hmm, es gibt keinen "einfachen" Proxy. Sie müssen mehrere Verbindungen verwalten (zumindest Client-to-Proxy und Proxy-to-Server), daher ist es wahrscheinlich am besten, sich zu untersuchen select(2)/poll(2)/epoll(4)/kqueue(2) System des Systemaufrufs, die es Ihnen ermöglichen Multiplex I/o. Dies wird normalerweise mit nicht blockierend Steckdosen. Schauen Sie sich Helferbibliotheken wie nach libevent. Schauen Sie sich an, wie dies in guten Webserver/Proxys wie möglich ist nginx. Klingt so, als ob Sie eine Menge für Sie entdecken können, aber keine Sorge, es macht Spaß :)

Eigentlich habe ich einen kleinen Web -Proxy mit meiner Bibliothek namens Rzsocket implementiert Link dazu.

Eines der schwierigsten Dinge, die ich bei der Implementierung des Web-Proxys gefunden habe, war vielleicht auch Ihr Problem, dass ich, um den Proxy ordnungsgemäß funktionieren zu lassen, die Einstellungen für die Keep-Alive-Einstellungen falsch festlegen musste. Eine Möglichkeit, dies in Firefox zu tun, ist der Zugriff Über: Konfiguration Adresse und Festlegen des Wertes von network.http.proxy.keep-alive zu false.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top