2012-05-08 7 views
1

プロキシサーバーを作成しようとしていますが、今はパイプライニングを実装したいと思います。私は問題に遭遇し、援助が必要です。私はthis質問をチェックしましたが、ソケットから読み取るデータがあるので、それは適用されないと思います。スレッドから実行するとソケットからのread()がハングアップする

主な考え方は次のとおりです。それぞれの接続に対して、それを処理するスレッドを作成します。この接続の各要求に対して、その要求を処理するスレッドを作成します。これまでのところ、私は最初の部分のコードを書いていて、正しく動作しています(スレッドは接続のすべての要求も処理します)。

これで、ソケットからの読み取りを試みるとき、要求処理スレッドからハングします。データの読み込みに使用する関数は以前と同じです(実際のバージョンでは)。

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:もっとコードが必要な場合は、教えてください。

EDIT

ここ

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

EDIT

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

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 

キープアライブフラグも削除しようとしましたが、それでも同じことが起こります。私は(accept(2)から)これはあなたの問題である推測してい

+0

ノンブロッキングソケットですか?また、部分書き込みを行う可能性があるため、 'write()'の回りにループを張る必要があります。 –

+0

はいこれは、非ブロッキングソケットです。 – gkaran89

+0

copydataを呼び出すコンテキストを追加してください。 lenは何から来ますか? – wuliang

答えて

2

Linuxでは、 accept()で返される新しいソケットは、リスニングソケットから O_NONBLOCKO_ASYNCなど ない継承ファイル状態フラグを行います。

I.e.新しいすべての受け入れられたソケットを非ブロッキングにする必要があります。

+0

'accept()'を 'accept4()'に変更し、 'SOCK_NONBLOCK'フラグを使ってこのトリックを行いました。情報のおかげで。 – gkaran89

関連する問題