【问题标题】:C program hanging while getting response from Flask serverC 程序在从 Flask 服务器获得响应时挂起
【发布时间】:2016-04-01 19:59:44
【问题描述】:

编辑在阅读了更多内容后,损坏的管道错误只是意味着我终止了连接。但问题仍然存在,为什么read 请求挂起?

我对此很陌生,所以请多多包涵。

我有一个在本地主机上运行的烧瓶中的小型 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 的其他一些答案,但不太了解如何将这些答案应用于我的情况(正如我所说,这是新的)。希望有任何正确方向的指示。

【问题讨论】:

  • 只是出于好奇,为什么要将它输入 c 程序?
  • 我想知道我自己有时...我在做 Matasano 问题,我开始用 C 做这些,所以到目前为止我实现的所有加密实用程序都是用 C 做的。我想过做C 语言中的 webapp 也是,但幸运的是我还有一些常识......
  • 只是把它扔在那里,如果你还没有听说过 cython,你应该去看看。你可以用它包装 c 库,然后导入 python。这是一个很好的介绍,他的书也很好(youtube.com/…
  • 谢谢,我会调查的!
  • 如果 c 代码相对较短,使用 cython 应该很容易启动和运行。 cython 对 c 代码进行优化,因此您从中获得的内容并导入到 python 中通常可以更有效地运行。在那个教程中,我链接了它展示了如何包装一个基本的 fib 函数。这是一个有趣的工具,imo。

标签: c http flask


【解决方案1】:

放弃上述方法并改用 cURL 使其工作。 (stringnewString 等是我自己的自定义字符串工具)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2020-06-12
    相关资源
    最近更新 更多