2011-11-09 4 views
0

Webページを閲覧するために、次のwin32ソケットプログラムを作成しました。私はランタイムへの依存を避けるためにwingwを使用しています。 ipaddressesを取得するには、www.google.com、www.yahoo.comなどのURLにコマンドプロンプトを使用してpingを実行し、プログラムでこれらのIPアドレスを使用します。ポートはofcourse 80です。私のWindowsソケットプログラムは、FireFox、IEなどのブラウザのいくつかのURLを開くことができません。

"GET/\ r \ n"を使用してGoogle、Yahooなどのデフォルトページを取得できます。また、 "GET /newsite/index.aspx"を使用して、http://yasini.com/newsite/index.aspxのようなディレクトリ内のものでも、デフォルト以外のページを取得することもできます。プログラムの出力は、ウェブサーバから受信したHTMLの形で、ハードディスクに保存されています。このファイルは後でfirefoxで開き、コミュニケーションはどのようになったのかを確認します。

私はfirefoxで開くことができるテストウェブページhttp://a.domaindlx.com/trysite/hello.aspを作成しました。次に、ドメインa.domaindlx.comにpingして、このipaddress、66.36.238.30を取得します。 "GET /trysite/hello.asp"を使って上記のページにアクセスしようとしましたが、 "このアドレスにはWebサイトが設定されていません。このアドレスにはWebサイトが設定されていません。

私は、上記の応答がWebサーバーによって送信されたことを知っていますので、Webサーバーに接続できました。問題は、ウェブサーバーが私がアクセスしようとしているURLを認識していないことです。私はhtmとaspの両方の異なるWebページを使用しており、誰もアクセス可能ではありません。

ブラウザで直接ipaddressを使用してウェブサイトを開こうとすると、「ウェブサイトが設定されていません...」という同じエラーが表示されます。

基本的なパズルがポート80

 

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

でWebサーバとの接続を開いた意味、私のコードは基本的にブラウザであるとき、なぜこれらのページは、Firefoxなどのブラウザ経由ではなく、私のコードからアクセスでき、あります

注:コードが機能するには、インクルード行にヘッダーファイル名を山括弧で囲んでください。私はhtmlをプロパティフォーマットに取り除かなければならなかった。

+0

優れたlibcurlライブラリを気にする必要はありませんか?ポータブル、固体、無料。 – rushman

答えて

0

プロトコルに正しく従っていません。あなたが望むGET /trysite/hello.asp HTTP/1.0\r\n\r\nフル仕様についてはhereを参照してください。

+0

私はこれを試してみましたが、webserverから次のメッセージを受け取りました:HTTP/1.0 404が見つかりませんサーバ:Microsoft-IIS/5.0日付:Wed、09 11月2011 19:42:59 GMT Content-Type:text/html Content- 111 X-Cache:lintoのMISS Connection:closeこのアドレスにはWebサイトは設定されていません。 Content-Length:111 X-Cache:lintoのMISS Connection:closeこのアドレスにはWebサイトは設定されていません。 Content-Length:111 X-Cache:lintoからのMISS接続:閉じる – Atif

+0

これは正常に動作しています。正しいフォーマットは次のとおりです。「http://a.domaindlx.com/trysite/my.htm HTTP/1.0 \ r \ n \ r \ n "プロトコル名とドメイン名を含む完全なURLを意味します。作業コードでは、strcat行を削除し、strcpy行を次のように置き換えなければなりません:strcpy(aa、 "GET http://a.domaindlx.com/trysite/my.htm HTTP/1.0 \ r \ n \ r \ n ");残りのコードは問題ありません。正しい方向に向かって私を指摘していただきありがとうございます。 – Atif

+1

私は、構文が一般にプロキシでの使用を意図していると考えていますが、すべてのタイプのクライアントで受け入れられるかもしれません。ほとんどのクライアントは、リクエストにHost:ヘッダーを追加します。例えば'GET /trysite/my.htm HTTP/1.0 \ r \ nHost:a.domaindlx.com \ r \ n \ r \ n' – Luke

0

問題のあるURLはサブドメインで実行されています。成功したURLはありません。多くのウェブサーバーは、同じ物理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として、パケットスニファを取得示唆しています。次に、実際にウェブブラウザ(または他のソケットアプリケーション)が送受信しているものを正確に見ることができます。その後、必要に応じてコード内でそれを一致させることができます。

0

コードには2つの問題があります。最初のものは、HTTP 1.0より前に\ r \ nではないスペースがあるはずです。これがなければあなたはHTTP 0.9を送信しています。

第2の問題は、いくつかのIPアドレスが複数のサイトをホストするために使用され、Hostヘッダーの送信を要求することです。

「このアドレスにWebサイトが設定されていません」と表示されているサイトでは、Host:ヘッダーを追加した方がうまく動作する可能性があります。そのサイトへのリクエストは、次のようになります。

"GET /trysite/hello.asp HTTP 1.0 \ rを\ nHost:a.domaindlx.com R \ nを\ rをする\ nは\"

関連する問題