请问怎么用C++来实现这个功能:http协议写的客户端。。谁有代码,与我共享一下吧。。我很着急学会。。可以吗??

解决方案 »

  1.   

    这是从网上找到的
    //
    // GetHTTP.cpp
    //
    // Retrieves a file using the Hyper Text Transfer Protocol
    // and prints its contents to stdout.
    ////
    // Pass the server name and full path of the file on the 
    // command line and redirect the output to a file. The program
    // prints messages to stderr as it progresses.
    //
    // Example:
    // GetHTTP www.idgbooks.com /index.html > index.html
    //#include <stdio.h>
    #include <fcntl.h>
    #include <io.h>
    #include <winsock.h>
    void GetHTTP(LPCSTR lpServerName, LPCSTR lpFileName);// Helper macro for displaying errors
    #define PRINTERROR(s) \
    fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())////////////////////////////////////////////////////////////void main(int argc, char **argv)
    {
    WORD wVersionRequested = MAKEWORD(1,1);
    WSADATA wsaData;
    int nRet; //
    // Check arguments
    //
    if (argc != 3)
    {
    fprintf(stderr,
    "\nSyntax: GetHTTP ServerName FullPathName\n");
    return;
    } //
    // Initialize WinSock.dll
    //
    nRet = WSAStartup(wVersionRequested, &wsaData);
    if (nRet)
    {
    fprintf(stderr,"\nWSAStartup(): %d\n", nRet);
    WSACleanup();
    return;
    }

    //
    // Check WinSock version
    //
    if (wsaData.wVersion != wVersionRequested)
    {
    fprintf(stderr,"\nWinSock version not supported\n");
    WSACleanup();
    return;
    } //
    // Set "stdout" to binary mode
    // so that redirection will work
    // for .gif and .jpg files
    //
    _setmode(_fileno(stdout), _O_BINARY); //
    // Call GetHTTP() to do all the work
    //
    GetHTTP(argv[1], argv[2]); //
    // Release WinSock
    //
    WSACleanup();
    }////////////////////////////////////////////////////////////void GetHTTP(LPCSTR lpServerName, LPCSTR lpFileName)
    {
    //
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    //
    IN_ADDR iaHost;
    LPHOSTENT lpHostEntry; iaHost.s_addr = inet_addr(lpServerName);
    if (iaHost.s_addr == INADDR_NONE)
    {
    // Wasn't an IP address string, assume it is a name
    lpHostEntry = gethostbyname(lpServerName);
    }
    else
    {
    // It was a valid IP address string
    lpHostEntry = gethostbyaddr((const char *)&iaHost, 
    sizeof(struct in_addr), AF_INET);
    }
    if (lpHostEntry == NULL)
    {
    PRINTERROR("gethostbyname()");
    return;
    }
    //
    // Create a TCP/IP stream socket
    //
    SOCKET Socket; Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Socket == INVALID_SOCKET)
    {
    PRINTERROR("socket()"); 
    return;
    }
    //
    // Find the port number for the HTTP service on TCP
    //
    LPSERVENT lpServEnt;
    SOCKADDR_IN saServer; lpServEnt = getservbyname("http", "tcp");
    if (lpServEnt == NULL)
    saServer.sin_port = htons(80);
    else
    saServer.sin_port = lpServEnt->s_port;
    //
    // Fill in the rest of the server address structure
    //
    saServer.sin_family = AF_INET;
    saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
    //
    // Connect the socket
    //
    int nRet; nRet = connect(Socket, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
    if (nRet == SOCKET_ERROR)
    {
    PRINTERROR("connect()");
    closesocket(Socket);
    return;
    }
    //
    // Format the HTTP request
    //
    char szBuffer[1024]; sprintf(szBuffer, "GET %s\n", lpFileName);
    nRet = send(Socket, szBuffer, strlen(szBuffer), 0);
    if (nRet == SOCKET_ERROR)
    {
    PRINTERROR("send()");
    closesocket(Socket);
    return;
    } //
    // Receive the file contents and print to stdout
    //
    while(1)
    {
    // Wait to receive, nRet = NumberOfBytesReceived
    nRet = recv(Socket, szBuffer, sizeof(szBuffer), 0);
    if (nRet == SOCKET_ERROR)
    {
    PRINTERROR("recv()");
    break;
    } fprintf(stderr,"\nrecv() returned %d bytes", nRet); // Did the server close the connection?
    if (nRet == 0)
    break;
    // Write to stdout
            fwrite(szBuffer, nRet, 1, stdout);
    }
    closesocket(Socket);
    }
      

  2.   

    to:rushman 
    很感谢你的指点,我试着运行了一下你发的代码,在编译的时候是没有错误的,但是BUILD时就出现了如下错误:
    GetHTTP.obj : error LNK2001: unresolved external symbol _WSACleanup@0
    GetHTTP.obj : error LNK2001: unresolved external symbol _WSAStartup@8
    GetHTTP.obj : error LNK2001: unresolved external symbol _recv@16
    GetHTTP.obj : error LNK2001: unresolved external symbol _send@16
    GetHTTP.obj : error LNK2001: unresolved external symbol _closesocket@4
    GetHTTP.obj : error LNK2001: unresolved external symbol _connect@12
    GetHTTP.obj : error LNK2001: unresolved external symbol _htons@4
    GetHTTP.obj : error LNK2001: unresolved external symbol _getservbyname@8
    GetHTTP.obj : error LNK2001: unresolved external symbol _socket@12
    GetHTTP.obj : error LNK2001: unresolved external symbol _WSAGetLastError@0
    GetHTTP.obj : error LNK2001: unresolved external symbol _gethostbyaddr@12
    GetHTTP.obj : error LNK2001: unresolved external symbol _gethostbyname@4
    GetHTTP.obj : error LNK2001: unresolved external symbol _inet_addr@4
    Debug/GetHTTP.exe : fatal error LNK1120: 13 unresolved externals
    Error executing link.exe.
    这些都没有接触过知道什么原因吗???
    高手指点一下谢谢
      

  3.   

    缺少ws2_32.lib库(windows sockets 2),把它添加到项目中。
      

  4.   


    #pragma  comment(lib,"ws2_32.lib")
      

  5.   

    多谢,错误没有啦。但是程序运行的时候为什么执行到:
    if (argc != 3)
        {
            fprintf(stderr,
                "\nSyntax: GetHTTP ServerName FullPathName\n");
            return;
        }
    执行到这里就结束了,根本没有调用GetHTTP()这个函数。我看到args返回值是41,不是3所以结束了。。但是它为什么输出41呢??什么情况下等于3呢???
      

  6.   

    "args"?"argc"?
    如果 argc 是 41 的话,那是命令行参数数目不对。你可以在命令行下带参数运行程序。
      

  7.   

    这个程序如果就是在命令行下自己输入参数来执行。那先看结构void main(int argc, char **argv) 肯定是传入两个参数,如果手动传入argc=3的话,就执行程序。但是我传入的值 是 3和另外的一个字符,不管输入什么字符,输出的结构都是:     :4325628  这个结果。什么原因????
      

  8.   

    哎,還是要學了基礎的東西再來搞別的啊,連C都沒搞明白別人給你代碼又有什麽用呢,argc是參數計數,這裡都已經寫得很明白了,要執行這個程式要以GetHTTP ServerName FullPathName這樣的命令行形式來執行.不是傳入個什麽3
      

  9.   

    因为需要指定域名和路径,所以要有两个参数(加上程序名,所以argc应该是3)。命令行格式:
    GetHTTP <域名> <站内路径>比如要访问:http://www.csdn.net/
    那么:
    GetHTTP www.csdn.net /