1

プロキシサーバーを作成しようとしていますが、今はパイプラインを実装したいと思っています。しかし、私は問題に遭遇し、支援が必要です。この質問を確認しましたが、ソケットから読み取るデータがあるため、当てはまらないと思います。

主なアイデアは次のとおりです。接続ごとにそれを処理するスレッドを作成し、この接続のリクエストごとにそのリクエストを処理するスレッドを作成します。これまでのところ、最初の部分のコードを書くことができ、それは正しく機能します(スレッドは接続のすべての要求も処理します)。

ソケットから、リクエスト処理スレッドから読み込もうとすると、ハングします。私がデータを読み取るために使用する機能は、以前と同じです(作業バージョン)。

void copydata(int from, int to, int len)
{
    char tbuff[BSIZ];
    int n;
    while (len > 0)
    {
        if ((n = read(from, tbuff, BSIZ)) <= 0) break;
        if (write(to, tbuff, n) < n) break;
        len -= n;
    }
}

from、to、len変数には適切な値があります(私はそれらをチェックしました)。そのような行動を引き起こす可能性のあるものはありますか?

PS:何かのためにもっとコードが必要な場合は、私に知らせてください。

編集

lenの取得方法は次のとおりです。

int contentlength(char *header)
{
    int len = INT_MAX;
    char line[MAX_LINE];

    if (HTTPheadervalue_case(header, "Content-Length", line)) sscanf(line, "%d", &len);
    return len;
}

copydataの呼び出し(activesocketはソケットを開く関数です):

if ((srv = activesocket(host, portno)) < 0)
    {
        sprintf(reshead, "HTTP/1.1 503\r\nContent-Length: 12\r\nConnection: close\r\n\r\nNon-existent");
        write(cli, reshead, strlen(reshead));
    } else
    {
        sprintf(reqhead1, "%s %s HTTP/1.1\r\n", "GET", path);
        if (HTTPheadervalue_case(reqhead1, "Connection", result)) if (strcasecmp(result, "close") == 0) cli_terminate[cli] = TRUE;
        strcat(reqhead1, reqhead);
        write(srv, reqhead1, strlen(reqhead1));
        while (completed[cli] != id)
            ;
        copydata(cli, srv, contentlength(reqhead));
        parseResponse(&srv, cli);
        completed[cli] = (completed[cli] + 1) % ULONG_MAX;
    }

編集

リクエストヘッダーの例は次のとおりです。

Host: www.google.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.16) Gecko/20120421 Iceweasel/3.5.16 (like Firefox/3.5.16)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
Cookie: cookie content

キープアライブフラグも削除しようとしましたが、それでも同じことが起こります。

4

1 に答える 1

2

私はこれがあなたの問題だと思います(からaccept(2)):

Linuxでは、によって返される新しいソケットは、リスニングソケットなどのファイルステータスフラグを継承しaccept()ません。O_NONBLOCKO_ASYNC

つまり、新しく受け入れられたすべてのソケットを明示的に非ブロッキングにする必要があります。

于 2012-05-08T14:37:59.667 に答える