2016-08-25 2 views
5

Ich möchte ein Programm machen, das Bilder aus Dateien greift, codiert sie und sendet sie an einen Server. Als der Server das Bild dekodieren soll, und speichern Sie es in der Datei. Ich habe die Bildcodierung selbst getestet, und es hat funktioniert, daher liegt das Problem in der Server- und Clientverbindung. HierPython Fehler: "socket.error: [Errno 11] Ressource vorübergehend nicht verfügbar" beim Senden von Bild

ist der Server:

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

Und hier ist der Kunde:

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

Und die Fehlermeldung lautet:

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 

Antwort

8

Im Server Sie die Fernbedienung einstellen Socket (das von accept() zurückgegeben wurde) in den nicht blockierenden Modus, was bedeutet, dass E/A an diesem Socket sofort beendet wird y durch eine Ausnahme, wenn keine Daten zum Lesen vorhanden sind.

Zwischen dem Verbindungsaufbau mit dem Server und den Bilddaten, die vom Client gesendet werden, wird normalerweise ein Zeitraum liegen. Der Server versucht, Daten vom Client sofort zu lesen, sobald die Verbindung akzeptiert wird. Es sind jedoch möglicherweise noch keine Daten zum Lesen vorhanden. Daher löst c.recv() eine Ausnahme vom Typ socket.error: [Errno 11] Resource temporarily unavailable aus. Errno 11 entspricht , also recv() abgebrochen, weil keine Daten zum Lesen bereit waren.

Ihr Code scheint keine nicht blockierenden Sockets zu erfordern, da sich accept() am Anfang der while-Schleife befindet und daher nur eine Verbindung gleichzeitig verarbeitet werden kann. Sie können den Anruf einfach zu c.setblocking(0) entfernen und dieses Problem sollte verschwinden.

+0

aber was mache ich, wenn der Server mehrere Verbindungen erhalten soll? –

+0

Das ist ein anderes Problem. Sie können 'select()' verwenden, um zu bestimmen, welche von mehreren Sockets zum Lesen bereit sind, und dann 'recv()' bei denen, die das sind, aufzurufen. Sie würden auch den Hauptserver-Socket zur Liste der Sockets hinzufügen, die an 'select()' übergeben werden, und call accept für diesen Socket aufrufen, wenn 'select()' anzeigt, dass es lesbar ist. Es gibt Alternativen im 'select' Modul wie' poll() 'et. al. – mhawke

+1

Sie können auch das Modul ['selectors'] (https://docs.python.org/3/library/selectors.html#module-selectors) oder [' asyncio'] (https: //docs.python .org/3/library/asyncio.html # module-asyncio), wenn Sie Python 3.4 oder höher verwenden. ['asyncore'] (https://docs.python.org/2.7/library/asyncore.html#module-asyncore) ist eine Option in Python 2. – mhawke

Verwandte Themen