2015-12-27 2 views
1

EDIT После некоторого более подробного описания ошибка сломанного трубопровода означает, что я прекратил соединение. Но вопрос остается, почему запрос read висит?С программная зависание при получении ответа от сервера фляг

Я очень новичок в этом, поэтому, пожалуйста, несите меня.

У меня крошечная веб-приложение в колбах, выполняющихся на локальном хосте, который выглядит следующим образом:

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, код, за который я заимствовал ответ Джереми Иеремии here. Насколько я могу судить, он открывает сокет и отправляет запрос, а затем он не может прочитать ответ. Я просто хочу знать, если веб-приложение возвращается 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); 

Он никогда не попадает в Printf после read(sockfd...). Если я прекратить программу 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 висит, реакция выглядит следующим образом:

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

просто из любопытства, зачем подавать это в программу c? – wgwz

+0

Мне интересно, что я иногда ... Я делаю проблемы с Матасано, я начал делать их на C, поэтому все криптовые утилиты, которые я реализовал до сих пор, находятся на C. Я думал о том, чтобы сделать webapp на C тоже, но, к счастью, У меня есть здравый смысл ... – gmoss

+1

просто выбросив его там, если вы не слышали о цитоне, вы должны это проверить. вы можете объединить c-библиотеки с ним, а затем импортировать в python. вот хорошее введение, его книга тоже хороша (https://www.youtube.com/watch?v=gMvkiQ-gOW8&index=10&list=PLYx7XA2nY5Gcpabmu61kKcToLz0FapmHu) – wgwz

ответ

1

Получил его, выполнив описанный выше подход и используя вместо этого cURL. (string, newString и т. Д. - это мои собственные пользовательские строки 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; 
} 
Смежные вопросы