无法让我的代理服务器向客户端发送http请求的信息 - 套接字编程

时间:2015-09-30 10:39:16

标签: c sockets proxy fork http-request

我的程序的目标是实现可以由单个客户端连接的代理服务器,并且只允许http请求。

要求

  1. 使用套接字创建基于C的客户端 - 服务器体系结构
  2. 代理服务器应该能够接受并维护单个客户端的http请求
  3. 代码

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

    代理服务器。

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

    我已经能够使用套接字实现简单的客户端 - 服务器交换,我的问题是Http请求。我必须使用GET方法通过端口80访问Web服务器。

    我有客户端发送到代理服务器的输入方式应该是:www.NAME.com

    在初始连接到客户端之后,服务器似乎没有做任何事情。

1 个答案:

答案 0 :(得分:0)

像往常一样,此处无法正确管理以null结尾的字符串。使用以下构造时

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

不会发送尾随空终止字符。在接收方面,存在两个问题。首先,recv(sock, buff, sizeof(buff));可以接收不可预测的字节数 - 从1到提供的字符串大小。因此,您需要阅读,直到您阅读所有消息。这就是困境 - 你怎么知道实际的消息有多长?答案是你要么事先就所有字符串的大小达成一致,要么总是发送那么多字节(不管实际的字符串长度),或者在字符串前面添加字符串的大小。第二个问题是,即使运气好整个字符串被读取,它也不会以空值终止,因此在程序中无法使用。它已手动以空值终止。