2015-09-30 1 views
0

Mon objectif de mes programmes est d'implémenter un serveur proxy qui peut être connecté par un seul client et permettrait seulement la requête http.impossible d'obtenir mon serveur proxy pour envoyer des informations http demandées à la programmation client-Socket

Les exigences

  1. Pour créer une architecture client-serveur à base de C en utilisant les sockets
  2. Le serveur proxy doit être en mesure d'accepter et de service unique client demande http

Code

client.c

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


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

int sockfd, portnum, n; 
struct sockaddr_in serv_addr; 
struct hostent *server; 

char buffer[256]; 
if(argc < 3){ 
    fprintf(stderr, "usage %s hostname port\n", argv[0]); 
    exit(1); 
} 
portnum = atoi(argv[2]); 
sockfd= socket(AF_INET, SOCK_STREAM, 0); 

if(sockfd <0){ 
perror("ERROR opening Socket"); 
exit(1); 
} 
server= gethostbyname(argv[1]); 
if(sockfd == NULL){ 
fprintf(stderr,"ERROR, no such host\n"); 
exit(1); 
} 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr, 
     server->h_length); 
serv_addr.sin_port = htons(portnum); 

if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) <0){ 
fprintf(stderr,"ERROR, on connecting"); 
exit(1); 
} 
printf("Please enter the Host name: "); 
bzero(buffer,256); 
fgets(buffer,255,stdin); 
n=write(sockfd,buffer,strlen(buffer)); 
if(n<0){ 
printf("Error writing to socket"); 
exit(1); 
} 

bzero(buffer,256); 
n=read(sockfd,buffer,255); 
if(n<0){ 
printf("ERROR reading from socket"); 
exit(1); 
} 
printf("%s\n", buffer); 


    return 0; 
    } 

Proxy server.c

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



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

int sockfd, newsockfd, portnum, clilen; 
char buffer[256], hostname[256]; 
pid_t p_id; 
struct sockaddr_in serv_addr, cli_addr; 
int n, pid; 

if(argc < 2){ 
    fprintf(stderr, "ERROR, NO PORT PROVIDED!\n"); 
    exit(1); 
} 
sockfd = socket(AF_INET, SOCK_STREAM, 0);//socket is made 

if(sockfd < 0){ 
    fprintf(stderr,"ERROR opening socket!!"); 
    exit(1); 
} 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
portnum = atoi(argv[1]);//port num 

serv_addr.sin_family = AF_INET; 
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
serv_addr.sin_port = htons(portnum); 


if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){ 
    fprintf(stderr,"ERROR on binding"); 
    exit(1); 
} 

if(listen(sockfd, 5) < 0){ 
printf("ERROR ON LISTEN"); 
exit(1); 
} 

    // accept 
     clilen = sizeof(cli_addr); 
    do{ 

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 
if(newsockfd<0){ 
    fprintf(stderr,"ERROR on accept\n"); 
    exit(1); 
} 

    pid=fork(); 
    if(pid==0){ 
bzero(buffer, 256); 
n= read(newsockfd, buffer, 255); 

if(n<0){//message from client 
fprintf(stderr,"ERROR Reading from socket\n"); 
exit(1); 
} 

strcpy(hostname, buffer); 
printf("Here is the hostname : %s\n", hostname); 

//variables used for acsessing webserver? 
int sockwb, wbport, x; 
struct sockaddr_in webser_addr; 
struct hostent *wbhost; 
char webbuf[510];//sending to webserver 

wbport =80;//port used to access web server 


    sockwb = socket(AF_INET, SOCK_STREAM, 0); 
    if(sockwb <0){ 
     printf("error opeing websocket\n"); 
     exit(1); 
    } 
    wbhost= gethostbyname(hostname); 
    printf("%s", wbhost->h_name); 
    if(sockwb == -1){ 
     printf("NO SUCH web HOST\n"); 
     exit(1); 
    } 
    bzero((char*) &webser_addr, sizeof(webser_addr)); 
    webser_addr.sin_family = AF_INET; 

     bcopy((char *)wbhost->h_addr,    
      (char *)&webser_addr.sin_addr.s_addr,  
      wbhost->h_length);    

    webser_addr.sin_port = htons(wbport); 
    if(connect(sockwb,(struct sockaddr *)&webser_addr,sizeof(webser_addr)) < 0){ 
     printf("error on web connecting\n"); 
     exit(1); 
    } 
    bzero(webbuf,510); 
    strcpy(webbuf, "GET http://"); 
    strcat(webbuf, hostname); 
    strcat(webbuf, " HTTP/1.1"); 

    printf("%s\n", webbuf); 
    x=write(sockwb,webbuf,strlen(webbuf)); 
    if(x<0){ 
     printf("error writing to web sock"); 
     exit(1); 
    } 
    bzero(webbuf,510); 
    x=read(sockwb,webbuf,510); 
    if(n<0){  
     printf("error reading from web socket"); 
     exit(1); 
    } 

n = write(newsockfd, webbuf,255);//write back to client 

if (n<0){ 
    fprintf(stderr,"ERROR WRITING to socket"); 
    exit(1); 
} 

printf("%s\n", webbuf); 
}//end of if pid==0 

printf("closing client"); 
close(newsockfd);//closing client socket 


    }while(1); 
    return 0; 
    } 

Je suis en mesure de mettre en œuvre d'un simple échange client-serveur avec les sockets, mon problème est à la demande Http. Je dois accéder au serveur Web via le port 80 en utilisant la méthode GET.

La façon dont j'ai l'entrée que le client envoie au serveur proxy doit être: www.NAME.com

Le serveur ne semble pas faire quoi que ce soit après la première connexion au client.

+0

Problèmes courants. Pas de gestion d'erreur correcte. Ignorer le compte renvoyé par 'recv()'. Réduction à zéro inutile des tampons. – EJP

+0

@EJP, Le vrai problème est, comme d'habitude, ne sachant pas comment gérer les chaînes à terminaison nulle. – SergeyA

+0

@SergeyA Je ne peux pas être d'accord avec cette formulation. Il n'y a pas de chaîne terminée par null pour gérer dans TCP. Le code TCP ne devrait pas supposer le contraire. Il devrait utiliser le compte renvoyé par 'recv()'. – EJP

Répondre

0

Comme d'habitude, les chaînes à terminaison nulle ne sont pas gérées correctement ici. Lorsque la construction suivante est utilisée

send(sock, buff, strlen(buf)); 

Le caractère de fin nul à la fin n'est pas envoyé. Du côté de la réception, il y a deux problèmes. Tout d'abord, recv(sock, buff, sizeof(buff)); peut recevoir une quantité imprévisible d'octets - de 1 à la taille de la chaîne fournie. Donc vous devez lire jusqu'à ce que vous lisiez tout le message. Voici le dilemme - comment savez-vous combien de temps est le message? La réponse est que vous êtes d'accord sur la taille de toutes les chaînes à l'avance, et que vous envoyez toujours autant d'octets (indépendamment de la longueur réelle de la chaîne) ou que vous préfixez la chaîne avec sa taille dans le message. Le deuxième problème est que même si par hasard la chaîne entière est lue, elle n'est pas terminée par un caractère nul et, en tant que telle, inutilisable dans le programme. Il doit être terminé par zéro manuellement.