首页 文章

我的Windows Socket程序无法打开一些像FireFox,IE等浏览器可以使用的URL

提问于
浏览
0

我已经制作了以下win32套接字程序来浏览网页 . 我使用wingw来避免依赖于任何运行时 . 为了获得ipaddresses,我通过命令提示符ping www.google.com,www.yahoo.com等网址,并在我的程序中使用这些ip addreses . 港口是80 .

我可以使用"GET /\r\n"获取谷歌,雅虎等的默认页面 . 我也可以通过使用"GET /newsite/index.aspx"来获取非默认页面,甚至是内部目录,例如http://yasini.com/newsite/index.aspx . 程序的输出是从网络服务器收到的html格式,保存在硬盘上 . 稍后在firefox中打开此文件以查看通信是如何进行的 .

我已经制作了一个测试网页http://a.domaindlx.com/trysite/hello.asp,我可以在firefox中打开它 . 然后我ping域名a.domaindlx.com并得到这个ipaddress,66.36.238.30 . 我尝试使用"GET /trysite/hello.asp"访问所述页面,但得到此回复,"No web site is configured at this address. No web site is configured at this address."

我知道上述响应是由网络服务器发送的,所以我能够连接到网络服务器 . 问题是网络服务器无法识别我尝试访问的网址 . 我使用了不同的网页,包括htm和asp,无法访问 .

当试图直接在浏览器中使用ipaddress打开网站时,我得到了同样的错误,“没有配置网站...” .

基本的难题是,为什么这些页面可以通过浏览器(如firefox)访问,而不是通过我的代码访问,当我的代码本质上是一个浏览器时,意味着与端口80上的webserver打开连接 .

#include windows.h
    #include stdio.h

    WSADATA ws;

    int d;
    char aa[1000];
    struct sockaddr_in a;
    SOCKET s;
    int li;

    void abc(char *p)
    {
        FILE *fp = fopen("c:\\data.htm", "a+");
        fprintf(fp, "%s\n", p);
        fclose(fp);
    }

    _stdcall WinMain (HINSTANCE i, HINSTANCE j, char * k, int l)
    {
        d = WSAStartup(0x101, &ws);
        sprintf(aa, "WSASTARTUP = %d", d);
        abc(aa);

        s = socket(AF_INET, SOCK_STREAM, 0);
        sprintf(aa, "SOCKET = %d", s);
        abc(aa);

        a.sin_family = AF_INET;
        a.sin_port = htons(80);
        //a.sin_addr.s_addr = inet_addr("74.125.236.145");
        a.sin_addr.s_addr = inet_addr("66.36.238.30"); //a.domaindlx.com
        //a.sin_addr.s_addr = inet_addr("206.225.85.18"); //www.domaindlx.com
        //a.sin_addr.s_addr = inet_addr("87.248.122.122"); //www.yahoo.com
        //a.sin_addr.s_addr = inet_addr("72.167.153.9"); //www.yasini.com
        d = connect(s, (struct sockaddr *) &a, sizeof(a));

        strcpy(aa, "GET /trysite/hello.asp\r\n");
        strcat(aa, "HTTP 1.0 \r\n\r\n");
        send(s, aa, sizeof(aa), 0);
        li = 1;

        while(li != 0)
        {
            li = recv(s, aa, 1000, 0);
            abc(aa);
        }
    }

注意:请将头文件名括在尖括号的include行中,以使代码生效 . 我不得不删除属性格式的html .

3 回答

  • 0

    您的代码有两个问题 . 第一个是在HTTP 1.0之前应该有一个不是\ r \ n的空格 . 没有这个你发送HTTP 0.9 .

    第二个问题是某些IP地址用于托管多个站点,并且需要发送主机头 .

    如果您添加Host:标头,则告诉您“此地址未配置网站”的网站可能会更好 . 您对该网站的请求应如下所示:

    “GET /trysite/hello.asp HTTP 1.0 \ r \ nHost:a.domaindlx.com \ r \ n \ r \ n”

  • 0

    您没有正确遵循协议 . 您想要 GET /trysite/hello.asp HTTP/1.0\r\n\r\n 请参阅here以获取完整规格 .

  • 0

    麻烦的URL在子域上运行 . 成功的URL不是 . 许多Web服务器在同一物理IP上托管多个帐户,因此他们需要知道正在请求哪个特定域/子域才能访问正确的帐户 . 您需要在请求中包含 Host 标头 .

    另请注意,当您调用 send() 发送请求时,您将发送 aa 缓冲区的整个1000个字节,这是错误的 . 您只需要发送您实际填写的内容 .

    最后,您通常不是很好地管理套接字 . 您需要更好的错误处理 .

    试试这个:

    #include <windows.h>
    #include <stdio.h>
    
    void abc(char *p, int l = -1)
    {
        FILE *fp = fopen("c:\\data.htm", "a+");
        if (fp)
        {
            if (l == -1) l = strlen(p);
            fwrite(p, 1, l, fp);
            fclose(fp);
        }
    }
    
    int WINAPI WinMain (HINSTANCE i, HINSTANCE j, char * k, int l)
    {
        char aa[1000];
    
        WSADATA ws;
        int d = WSAStartup(0x101, &ws);
        sprintf(aa, "WSASTARTUP = %d\n", d);
        abc(aa);
    
        if (d == 0)
        {
            SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
            sprintf(aa, "SOCKET = %d\n", s);
            abc(aa);
    
            if (s != INVALID_SOCKET)
            {
                char *host = "a.domaindlx.com";
                char *file = "/trysite/hello.asp";
    
                struct sockaddr_in a;
                memset(&a, 0, sizeof(a));
    
                a.sin_family = AF_INET;
                a.sin_port = htons(80);
    
                struct hostent *h = gethostbyname(host);
                if (!h)
                {
                    sprintf(aa, "gethostbyname(\"%s\") FAILED\n", host);
                    abc(aa);
                }
                else
                {
                    sprintf(aa, "gethostbyname(\"%s\") TYPE = %d\n", host, h->h_addrtype);
                    abc(aa);
    
                    if (h->h_addrtype == AF_INET)
                    {
                        a.sin_addr = * (struct in_addr*) h->h_addr;
                        sprintf(aa, "gethostbyname(\"%s\") IP = %s\n", host, inet_ntoa(a.sin_addr));
                        abc(aa);
    
                        d = connect(s, (struct sockaddr *) &a, sizeof(a));
                        sprintf(aa, "CONNECT = %d\n", d);
                        abc(aa);
    
                        if (d == 0)
                        {
                            sprintf(aa,
                                "GET %s HTTP/1.0\r\n"
                                "Host: %s\r\n"
                                "Connection: close\r\n"
                                "\r\n",
                                file, host);
    
                            char *p = aa;
                            int t = strlen(aa);
                            int li;
    
                            do
                            {
                                li = send(s, p, t, 0);
                                if (li < 1)
                                    break;
    
                                p += li;
                                t -= li;
                            }
                            while (t > 0);
    
                            if (t != 0)
                            {
                                abc("SEND FAILED\n");
                            }
                            else
                            {
                                abc("SEND OK\n");
    
                                do
                                {
                                    li = recv(s, aa, sizeof(aa), 0);
                                    if (li < 1)
                                        break;
    
                                    abc(aa, li);
                                }
                                while (true);
                            }
                        }
                    }
                }
    
                closesocket(s);
            }
    
            WSACleanup();
        }
    
        return 0;
    }
    

    我强烈建议您使用数据包嗅探器,例如Wireshark . 然后,您可以确切地看到Web浏览器(或任何其他套接字应用程序)实际发送和接收的内容 . 然后,您可以根据需要在代码中匹配它 .

相关问题