3

私はソケットを扱うのはかなり初めてで、最初のプロジェクトの 1 つに取り組んでいます。最初のものは、実際にはライブラリなしで完全に完了するつもりです。WinAPIのみを使用して、Windows 7を使用しています。

私は学校で部分的に取り組んでおり、私の学校には Web フィルター、FortiGuard があると思います。google.com などの Web ブラウザーでページを開こうとしたときに許可されているドメインでページを取得しようとしても、次のメッセージが返されます。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">html,body{height:100%;padding:0;margin:0;}.oc{display:table;width:100%;height:100%;}.ic{display:table-cell;vertical-align:middle;height:100%;}div.msg{display:block;border:1px solid#30c;padding:0;width:500px;font-family:helvetica,sans-serif;margin:10px auto;}h1{font-weight:bold;color:#fff;font-size:14px;margin:0;padding:2px;text-align:center;background: #30c;}p{font-size:12px;margin:15px auto;width:75%;font-family:helvetica,sans-serif;text-align:left;}</style>
<title>The URL you requested has been blocked</title>
</head>
<body><div class="oc"><div class="ic"><div class="msg"><h1>The URL you requested has been blocked</h1><p>The page you have requested has been blocked, because the URL is banned.<br /><br />URL = invalid<br /></p></div></div></div></body>
</html>

(私はそれを少し分解しようとしました)。

ご覧のとおり、URL は禁止されています。学校にいるときにのみ発生するため、これは Web フィルターだと思います。

少なくとも、Web ブラウザーで正常に動作する Web サイトに対して正しい標準 HTTP GET 要求を使用していると信じていますが、このメッセージを受け取りました。ソケットリクエストに何か問題がありますか?

これが私のソケットコードです:

すべての関数に渡す基本的な「socket_t」構造があります。その定義は次のとおりです。

//custom socket structure
typedef struct
{
    //windows-specific
    struct sockaddr win_addr;
    u_long mode;
    SOCKET socket;//acutal SOCKET structure

    // General
    bool listening;//set to true if actively listening
    bool thread_terminate;//when boolean is set to true, listening thread terminates
    void (*error_callback) (int);
    http_response_t * response;
} socket_t;

接続の場合:

//see socket_t definition in socket.h
//returns 0 on success, SOCKET_ERROR on WinSock failure, positive error code on DNS failure
int socket_connect(socket_t * sock, char * addr, int port)
{
    //bear in mind sock is the custom socket_t structure.  sock->socket is the actual SOCKET structure.
    //pardon the nomenclature.  rookie code.
    //TODO:  IPv6 support?

    //DNS lookup structures
    struct addrinfo *   res             = NULL;// Result of the getaddrinfo() call
    struct sockaddr *   sockaddr_v4     = NULL;// IPv4 sockaddr structure

    // So-called "hints" structure detailed in the getaddrinfo() MSDN page.
    // I guess it contains information for the DNS lookup.
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family     = AF_UNSPEC;
    hints.ai_socktype   = SOCK_STREAM;
    hints.ai_protocol   = IPPROTO_TCP;

    //Perform DNS lookup
    DWORD getaddrinfo_res = getaddrinfo(addr, "80\0", &hints, &res);//hardcode port number, for now
    if(getaddrinfo_res != 0) return getaddrinfo_res;

    //for each
    for(struct addrinfo * ptr = res; ptr != NULL; ptr = ptr->ai_next)
    {
        switch(ptr->ai_family)
        {
        case AF_INET:
            sockaddr_v4 = (struct sockaddr *) ptr->ai_addr;//set current address
            sock->win_addr = * sockaddr_v4;//set socket address
        }
    }

    //initialize actual SOCKET
    sock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// TCP/IP, stream-oriented, and TCP rather than UDP; respectively
    if(sock->socket == INVALID_SOCKET) return SOCKET_ERROR;

    //actual connection
    int connect_res = connect(sock->socket, &(sock->win_addr), sizeof(sock->win_addr));
    if(connect_res == SOCKET_ERROR) return SOCKET_ERROR;
    return 0;
}

HTTP リクエスト ビット:

// Execute an HTTP request.
// Param 1: socket_t object
// Param 2: resource locator not including site name.
int socket_httprequest(socket_t * sock, char * rl)
{
    std::string str_req = std::string("GET /");
                str_req.append(rl);
                str_req.append(" HTTP/1.0\r\n");

                /*
                //user agent header
                str_req.append("User-Agent: conley-client/");
                str_req.append(VERSION);
                str_req.append("\r\n");
                */

                //final newline
                str_req.append("\r\n");

    const char * z_req = str_req.c_str();
    return send(sock->socket, z_req, (int) strlen(z_req), 0);
}

それらはすべて次のようにメイン関数で呼び出されます。

// Initialization
conley::init_sockets();
conley::init_http();

conley::socket_t * sock = conley::socket_alloc(err_callback);
int connect_res = conley::socket_connect(sock, "google.com\0", 80);
if(connect_res > 0) std::cout << "DNS ERR " << connect_res << std::endl;
if(connect_res < 0) std::cout << "CONNECT ERR " << WSAGetLastError() << std::endl;
if(connect_res == 0) std::cout << "Connected" << std::endl;

int httpreq_res = conley::socket_httprequest(sock, "\0");
if(httpreq_res != -1) std::cout << "HTTP request success: " << httpreq_res << " bytes sent" << std::endl;
else std::cout << "HTTP request failure: Error " << WSAGetLastError() << std::endl;

conley::socket_listen(sock);

お時間をいただきありがとうございます!

4

1 に答える 1

1

おそらく、エラーの原因はプログラムではなく、リクエストがブラウザから送信されたものではないことをフィルタが検出したためです。ブラウザーは、ユーザー エージェントなどのヘッダーを送信して、要求を送信したサーバーに自身を識別させます。私のアドバイスは、 Wiresharkのようなツールを使用して、ブラウザーによって生成されたトラフィックをキャプチャし、アプリケーションからそれを模倣することです。

于 2013-11-27T15:13:50.767 に答える