从Flask服务器获得响应时C程序挂起

时间:2015-12-27 22:31:34

标签: c http flask

编辑经过多次阅读后,破损的管道错误只是意味着我终止了连接。但问题仍然存在,为什么read请求悬而未决?

我对此很陌生,请耐心等待。

我在localhost上运行了一个小小的webapp,看起来像这样:

import stuff
app = Flask(__name__)
...do some stuff
@app.route("/")
def foo():

    resp_OK = Response(response="", status=200)
    resp_NO = Response(response="", status=500)

    ...do some stuff

    if some stuff:
        return resp_NO
    else:
        return resp_OK

if __name__== '__main__':
    app.run()

如果我只输入localhost:5000/?param1=therightparamts&param2=tomakeitwork,一切正常,命令行响应相应为200或500.

现在,我正试图从C里面得到这个回应,这是我从Jeremy Jeremiah的回复中借来的代码here。据我所知,它打开套接字并发送请求,然后它无法读取响应。我只是想知道webapp是否返回200或500.这是C代码的相关部分:

char response[4096];
int total, received, bytes;
...
sockfd = socket(AF_INET, SOCK_STREAM, 0);
...
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    error("ERROR connecting");
...
do {
    bytes = write(sockfd,&(message.c[sent]),total-sent);
    ...}while(...);
...
memset(response,0,sizeof(response));
total = sizeof(response)-1;
received = 0;
do {
    bytes = read(sockfd,response+received,total-received);
    printf("Read %i bytes.\n", received); fflush(stdout);
    if (bytes < 0)
        error("ERROR reading response from socket");
    if (bytes == 0)
        break;
    received+=bytes;
} while (received < total);

read(sockfd...)之后永远不会到达printf。如果我挂起C程序,控制台输出

127.0.0.1 - - [27/Dec/2015 14:25:33] "GET /?file=foo&signature=46b4ec586117154dacd49d664e5d63fdc88efb51 HTTP/1.1" 500 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 2363)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 657, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 716, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------

如果我在C程序挂起时键盘中断了webapp,响应如下:

Exception happened during processing of request from ('127.0.0.1', 3760)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 655, in __init__
    self.handle()
  File "/home/gmoss/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 217, in handle
    rv = BaseHTTPRequestHandler.handle(self)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/home/gmoss/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 251, in handle_one_request
    elif self.parse_request():
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 291, in parse_request
    self.headers = self.MessageClass(self.rfile, 0)
  File "/usr/lib/python2.7/mimetools.py", line 25, in __init__
    rfc822.Message.__init__(self, fp, seekable)
  File "/usr/lib/python2.7/rfc822.py", line 108, in __init__
    self.readheaders()
  File "/usr/lib/python2.7/rfc822.py", line 155, in readheaders
    line = self.fp.readline()
  File "/usr/lib/python2.7/socket.py", line 451, in readline
    data = self._sock.recv(self._rbufsize)
KeyboardInterrupt
----------------------------------------

我在SO上查看了其他一些答案,但不太明白如何将这些答案应用到我的情况中(正如我所说,对此我不熟悉)。非常感谢任何指向正确的方向。

1 个答案:

答案 0 :(得分:1)

通过放弃上述方法并使用cURL来实现它。 (stringnewString等是我自己的自定义字符串utils。)。

int curlRequest(int argc, string *argv)
{
  CURL *curl;
  CURLcode res;
  string url;
  int i;
  long http_code;

  url=newString("http://localhost:5000",0);
  /* fill in the parameters */
  url=stringCat(url, newString("/?",0));
  for(i=0; i<argc; i++){
    url = stringCat(url, argv[i]);
    if(i+1<argc) url = stringCat(url, newString("&",0));
  }
  //url = stringCat(url, newString(" HTTP/1.1\r\n",0));


  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, url.c);

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return http_code;
}