2016-08-25 69 views
5

我想制作一个程序,用于从文件访问图像,对它们进行编码并将它们发送到服务器。 比服务器应该解码图像,并将其保存到文件。 我测试了图像编码本身,它工作,所以问题在于服务器和客户端连接。Python错误:“socket.error:[Errno 11]资源暂时不可用”发送图像时

这里是服务器:

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() 

这里是客户端:

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() 

和错误消息是:

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 

回答

8

在服务器要设置远程套接字(由accept()返回)转换为非阻塞模式,这意味着该套接字上的I/O将立即终止如果没有要读取的数据,则由异常排除。

建立与服务器的连接和客户端发送的图像数据之间通常会有一段时间。一旦连接被接受,服务器将尝试立即从客户端读取数据,但是,可能没有任何数据要读取,因此c.recv()会产生socket.error: [Errno 11] Resource temporarily unavailable异常。 Errno 11对应于EWOULDBLOCK,因此recv()中止,因为没有数据准备好读取。

您的代码似乎不需要非阻塞套接字,因为在while循环的顶部有一个accept(),因此一次只能处理一个连接。您可以删除对c.setblocking(0)的呼叫,此问题应该消失。

+0

但我该怎么做,如果服务器应该得到多个连接? –

+0

这是另一个问题。您可以使用'select()'来确定多个套接字中的哪一个准备好读取,然后在那些套接字上调用'recv()'。您还可以将主服务器套接字添加到传递给'select()'的套接字列表中,只要select()指示它可读,就调用该套接字上的accept。在'select'模块中还有其他的选择,比如'poll()'et。人。 – mhawke

+1

您也可以考虑使用['selectors'](https://docs.python.org/3/library/selectors.html#module-selectors)模块或['asyncio'](https://docs.python .org/3/library/asyncio.html#module-asyncio)如果您使用Python 3.4或更高版本。 ['asyncore'](https://docs.python.org/2.7/library/asyncore.html#module-asyncore)是Python 2的一个选项。 – mhawke

相关问题