2012-05-08 120 views
1

我想写一个代理服务器,现在我想要实现流水线。我遇到了一个问题,但需要帮助。我检查了this的问题,但我认为它不适用,因为我确实有数据要从套接字读取。从套接字读()从线程挂起时挂起

主要想法如下。对于每个连接,我创建一个处理它的线程,并为此连接中的每个请求创建一个处理该请求的线程。到目前为止,我已经设法编写了第一部分的代码,并且它可以正常工作(线程还处理连接的所有请求)。

现在,当我试图从请求处理线程读取套接字时,它挂起。我用来读取数据的功能与以前相同(在工作版本中)。

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 

我试图剥离keep-alive标志,但仍然发生同样的情况。

+0

它是一个非阻塞套接字?此外,还需要围绕'write()'进行循环,因为它可能会执行部分写操作。 –

+0

是的,它是一个无阻塞的插座。 – gkaran89

+0

请添加一些调用copydata的上下文。 len从哪里来? – wuliang

回答

2

我猜这是你的问题(从accept(2)):

在Linux上,通过 accept()返回新的socket做 继承文件状态标志,如从监听套接字 O_NONBLOCKO_ASYNC

即,你需要明确地使每个新接受的套接字都是非阻塞的。

+0

将'accept()'更改为'accept4()'并使用'SOCK_NONBLOCK'标志取得了诀窍。感谢您的信息。 – gkaran89