2016-08-25 22 views
5

Tôi muốn tạo một chương trình truy cập hình ảnh từ tệp, mã hóa chúng và gửi chúng đến máy chủ. Hơn máy chủ được yêu cầu giải mã hình ảnh và lưu nó vào tệp. Tôi đã thử nghiệm bản thân mã hóa hình ảnh và nó hoạt động, vì vậy vấn đề nằm trong kết nối máy chủ và máy khách.Lỗi Python: "socket.error: [Errno 11] Tài nguyên tạm thời không khả dụng" khi gửi hình ảnh

Đây là máy chủ:

import socket 
import errno 
import base64 

from PIL import Image 
import StringIO 

def connect(c): 
    try: 
     image = c.recv(8192) 
     return image 
    except IOError as e: 
     if e.errno == errno.EWOULDBLOCK: 
      connect(c) 


def Main(): 
    host = '138.106.180.21' 
    port = 12345 

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


    while True: 

     c, addr = s.accept() 
     c.setblocking(0) 

     print "Connection from: " + str(addr) 

     image = c.recv(8192)#connect(c) 

     imgname = 'test.png' 

     fh = open(imgname, "wb") 
     if image == 'cusdom_image': 
      with open('images.png', "rb") as imageFile: 
       image = '' 
       image = base64.b64encode(imageFile.read()) 
       print image 
     fh.write(image.decode('base64')) 
     fh.close() 


if __name__ == '__main__': 
    Main() 

Và đây là các khách hàng:

import socket 
import base64 

from PIL import Image 
import StringIO 
import os, sys 

ip = '138.106.180.21' 
port = 12345 
print 'Add event executed' 
s = socket.socket() 
s.connect((ip, port)) 

image_path = '/home/gilgamesch/Bilder/Bildschirmfoto.png' 

print os.getcwd() 
olddir = os.getcwd() 
os.chdir('/') 
print os.getcwd() 

if image_path != '': 
    with open(image_path, "rb") as imageFile: 
     image_data = base64.b64encode(imageFile.read()) 
     print 'open worked' 
else: 
    image_data = 'cusdom_image' 

os.chdir(olddir) 

s.send(image_data) 


s.close() 

Và thông báo lỗi là:

Traceback (most recent call last): 
    File "imgserv.py", line 49, in <module> 
    Main() 
    File "imgserv.py", line 34, in Main 
    image = c.recv(8192)#connect(c) 
socket.error: [Errno 11] Resource temporarily unavailable 

Trả lời

8

Trong máy chủ bạn đang thiết điều khiển từ xa socket (được trả về bởi accept()) về chế độ không chặn, có nghĩa là I/O trên socket đó sẽ chấm dứt ngay y bởi một ngoại lệ nếu không có dữ liệu để đọc.

Thường sẽ có một khoảng thời gian giữa việc thiết lập kết nối với máy chủ và dữ liệu hình ảnh được gửi bởi ứng dụng khách. Máy chủ cố gắng đọc dữ liệu ngay lập tức từ máy khách khi kết nối được chấp nhận, tuy nhiên, có thể không có bất kỳ dữ liệu nào để đọc, do đó, c.recv() đặt ra một ngoại lệ socket.error: [Errno 11] Resource temporarily unavailable. Errno 11 tương ứng với EWOULDBLOCK, vì vậy recv() bị hủy vì không có sẵn dữ liệu để đọc.

Mã của bạn dường như không yêu cầu ổ cắm không chặn vì có accept() ở đầu vòng lặp while và do đó chỉ có thể xử lý một kết nối tại một thời điểm. Bạn chỉ có thể xóa cuộc gọi đến c.setblocking(0) và sự cố này sẽ biến mất.

+0

nhưng tôi phải làm gì nếu máy chủ được cho là có nhiều kết nối? –

+0

Đó là một vấn đề khác. Bạn có thể sử dụng 'select()' để xác định xem có nhiều socket nào đã sẵn sàng để đọc, và sau đó gọi 'recv()' trên những cái đang có. Bạn cũng sẽ thêm socket máy chủ chính vào danh sách các socket được chuyển tới 'select()' và gọi chấp nhận trên socket đó bất cứ khi nào 'select()' chỉ ra rằng nó có thể đọc được. Có các lựa chọn thay thế trong mô-đun 'select' như' poll() 'et. al. – mhawke

+1

Bạn cũng có thể xem xét sử dụng mô-đun ['selectors'] (https://docs.python.org/3/library/selectors.html#module-selectors) hoặc [' asyncio'] (https: //docs.python .org/3/library/asyncio.html # module-asyncio) nếu bạn đang sử dụng Python 3.4 hoặc mới hơn. ['asyncore'] (https://docs.python.org/2.7/library/asyncore.html#module-asyncore) là một tùy chọn trên Python 2. – mhawke

Các vấn đề liên quan