2016-05-22 3 views
0

Мне немного сложно получить изображение с помощью сокетов. Я думаю, проблема связана с тем, что сокеты отправляют как заголовок, так и фактическое изображение, и что эти два требуют различного декодирования.Получение изображения с использованием Python 3 Sockets

Это код:

import socket 

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
mysock.connect(('www.py4inf.com', 80)) 

mysock.send(
    'GET http://www.py4inf.com/cover.jpg HTTP/1.0\n\n'.encode('utf-8')) 
count = 0 
fhand = open("stuff.jpg", "wb") 
while True: 
    data = mysock.recv(512) 
    if len(data) < 1: 
     break 
    fhand.write(data) 
mysock.close() 
fhand.close() 
+0

У вас ** есть ** для использования сокетов? –

+0

Да. Я знаю способ urllib.request: 'from urllib.request import urlopen img = urlopen ('http://www.py4inf.com/cover.jpg') .read() fhand = open ('cover.jpg' , 'wb') fhand.write (img) fhand.close() ' –

ответ

1

Да, есть заголовок. Конец его после первой последовательности \ r \ n \ r \ n. Как только вы увидите эту последовательность, отправьте остальные в файл. Вот грубое исправление:

import socket 

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as mysock: 
    mysock.connect(('www.py4inf.com', 80)) 
    mysock.send(b'GET http://www.py4inf.com/cover.jpg HTTP/1.0\n\n') 
    header = b'' 
    while True: 
     data = mysock.recv(512) 
     if not data: 
      raise RuntimeError('no header?') 
     header += data 
     # end-of-header in buffer yet? 
     eoh = header.find(b'\r\n\r\n') 
     if eoh != -1: 
      break 
    # split the header off and keep data read after it. 
    header,data = header[:eoh+4],header[eoh+4:] 
    print(header.decode()) 
    with open("stuff.jpg", "wb") as fhand: 
     fhand.write(data) 
     while True: 
      data = mysock.recv(512) 
      if not data: 
       break 
      fhand.write(data) 

Вот заголовок. Обратите внимание, что длина содержимого находится в заголовке, поэтому, если вы хотите отправить HTTP-запрос с помощью keepalive, вам нужно будет прочитать точно столько же байтов после заголовка. поскольку указывается Connection: close, вам нужно только прочитать, пока не будет получено больше данных.

HTTP/1.1 200 OK 
Date: Sun, 22 May 2016 23:22:20 GMT 
Server: Apache 
Last-Modified: Fri, 04 Dec 2015 19:05:04 GMT 
ETag: "b294001f-111a9-526172f5b7cc9" 
Accept-Ranges: bytes 
Content-Length: 70057 
Connection: close 
Content-Type: image/jpeg 
Смежные вопросы