2016-09-15 9 views
1

Im в настоящее время создаю http-сервер сокета python, и я работаю над своими запросами GET и POST. Я успешно выполнил свою реализацию GET, но элемент body запросов POST не появится. Фрагмент кода:http POST сообщение тела не получено

self.host = '' 
self.port = 8080 

self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
self.listener.bind((self.host, self.port)) 
self.listener.listen(1) 

while True: 

     client_connection, client_address = self.listener.accept() 
     request = client_connection.recv(2048) 
     print request 

Этот код дает заголовок HTTP после обработки запроса на запись с веб-страницы:

POST /test.txt HTTP/1.1 
Host: localhost:8080 
Content-Type: application/x-www-form-urlencoded 
Origin: http://localhost:8080 
Content-Length: 21 
Connection: keep-alive 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17 
Referer: http://localhost:8080/ 
Accept-Language: nb-no 
Accept-Encoding: gzip, deflate 

Но нет тела, поэтому вопрос, почему я не получаю НТТР тело, когда я знаю, что он отправлен?

Спасибо!

+0

Вопрос: почему вы не показываете код КЛИЕНТА, где POST был изначально построен? –

+0

hi @MarcB проект предназначен для назначения класса, а клиентская сторона уже реализована. Я должен только реализовать серверную часть для обработки запросов GET и POST. Так что я предполагаю, что его серверная сторона получила ошибки – mmoe

+0

, какие ошибки? сервер просто выплевывает то, что получил. если он не получает тело сообщения, возможно, вы должны проверить, действительно ли клиент работает правильно. –

ответ

0
while True: 

     client_connection, client_address = self.listener.accept() 
     request = client_connection.recv(2048) 
     print request 

recv не читает ровно 2048 байт, но он читает до 2048 байт. Если некоторые данные поступят, то recv вернется с данными, даже если последует больше данных. Я предполагаю, что в вашем случае клиент сначала отправляет HTTP-заголовок, а затем тело. Если алгоритмы NAGLE отключены на стороне клиента (общие), вероятно, ваш первый recv получит только заголовок и вам понадобится еще один recv для тела. Это объясняет, что происходит в вашем случае: вы получаете заголовок, но не тело, так как вы не делаете другого recv.

Но даже это было бы слишком простой реализацией, которая рано или поздно пойдет не так. Чтобы сделать это правильно, вы должны правильно реализовать протокол HTTP: сначала прочтите HTTP-заголовок, который может потребоваться несколько recv, если заголовок большой. Затем вы должны разобрать заголовок, выяснить размер тела (Content-length) и прочитать оставшиеся байты.

+0

безупречный! оказалось, что сервер прекратил получать данные после заголовка, вызвав новый socket.recv с длиной контента, сделал трюк! спасибо – mmoe

+0

@mmoe: но снова. Не рассчитывайте на то, что вы получите полный заголовок с первым recv и телом со следующим. Протокол, лежащий в основе HTTP, - это TCP, и это протокол потока, который не имеет границ неявного сообщения. Правильный способ - просто прочитать данные, пока вы не нашли конец заголовка (т. Е. Пустую строку) –