Http客户端程序使用socket无法正常工作

时间:2013-02-15 06:06:30

标签: c http sockets network-programming httpclient

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


/* getLine() Reads a line from a stream and stores it in "string"


 size_t getLine(char **string, FILE *stream)
 {
 size_t rd=0;
 char s;
 int ln = getline(string,&rd,stream);

 if(ln == -1)
 {

 return -1;
 }
 return rd;
 }


 /* Convert file descriptor into stream (i.e., FILE*).  Exit if there is a
 * failure. */

FILE* getStream(int sock)
{
    FILE *fp;
    fp = fdopen(sock,"a+b");

    if(fp == NULL)
    {
        fprintf(stderr,"error opening socket\n");
        exit(EXIT_FAILURE);
    }

    return fp;
}

/* Creates a TCP socket and returns the file descriptor for it. */

int createSocket(char *hostname, char *port)
{
    if(hostname == NULL || port == NULL)
    {
        fprintf(stderr, "One or more parameters passed to createSocket() are NULL\n");
        exit(EXIT_FAILURE);
    }

    /* Request a TCP connection using the version of IP that is configured
     on the machine.
     */

    struct addrinfo * result, *h;
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG;

    int error = getaddrinfo(hostname, "http", &hints, &result);

    if(error != 0)
    {
        fprintf(stderr,"\n error in getaddrinfo:%s\n",gai_strerror(error));
        exit(EXIT_FAILURE);
    }

    /* TODO: Create a socket using socket() and the "result" structure.
     Check for an error. If one occurs, print a message and exit.
     */


    for(h=result; h != NULL; h = h->ai_next)
    {
        int sock = socket(h->ai_family, h->ai_socktype, h->ai_protocol);

        if(sock == -1)
        {
            fprintf(stderr,"\nerror in creating Socket");
            exit(EXIT_FAILURE);
        }



        /* TODO: Call connect() with "sock" and information from the
         "result" struct to start a TCP connection. Check for error. If
         one occurs, print message and exit.
         */

        if(connect(sock, h->ai_addr, h->ai_addrlen) == -1)
        {
            fprintf(stderr,"\nerror in connecting");
            exit(EXIT_FAILURE);
        }

        freeaddrinfo(result);
        return sock;

    }
}


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

    /* TODO: Check number of arguments */

    if(argc<2)
    {
        printf("expected a name for resolving");
        exit(1);
    }

    /* Setup socket. */

    int sock = createSocket(argv[1], argv[2]);
    FILE *stream = getStream(sock);
    printf("\n###### CLIENT IS SENDING THE FOLLOWING TO THE SERVER\n");


    /* TODO: Write HTTP request to "stream" */

    printf(" GET / HTTP/1.0\n Host: %s\n Connection: close \r\n \r\n", argv[1]);
    fprintf(stream, "GET / HTTP/1.0\n Host: %s\n Connection: close \r\n \r\n", argv[1]);

    while(1) // while there is data to read
    {
        char *string = NULL;
        printf("#####CLIENT RECEIVED THE FOLLOWING FROM SERVER\n");
        int len = getLine(&string, stream);
        printf("%s",string);
        while((len=getLine(&string, stream)) != -1)
        {
            printf("%s",string);
        }


        fclose(stream);
        printf("\n##### Connection closed by server\n");
        exit(EXIT_SUCCESS);
        free(string);

    } // end infinite loop
}

2 个答案:

答案 0 :(得分:3)

您不尊重HTTP protocol specification。它显然要求您使用CRLF终止请求标头中的每一行,这意味着\ r \ n。在您的情况下,您只使用LF终止某些行,因此服务器的行为是未定义的。

答案 1 :(得分:1)

您可以使用curl库来构建http(s)请求。 看看这个

http://curl.haxx.se/libcurl/