web-dev-qa-db-fra.com

Python erreur: "socket.error: [Errno 11] Ressource temporairement indisponible" lors de l'envoi de l'image

Je veux créer un programme qui accède aux images à partir de fichiers, les code et les envoie à un serveur. Ensuite, le serveur est censé décoder l'image et l'enregistrer dans un fichier. J'ai testé l'image elle-même et cela a fonctionné, donc le problème réside dans la connexion serveur et client.

Voici le serveur:

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

Et voici le client:

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

Et le message d'erreur est:

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
Gilgamesch von Uruk

Dans le serveur, vous définissez le socket distant (celui renvoyé par accept()) en mode non bloquant, ce qui signifie que les E/S sur ce socket se termineront immédiatement par une exception s'il n'y a pas de données à lire.

Il y aura généralement un certain temps entre l'établissement de la connexion avec le serveur et les données d'image envoyées par le client. Le serveur tente de lire immédiatement les données du client une fois la connexion acceptée, mais il se peut qu'il n'y ait pas encore de données à lire, donc c.recv() lève une exception socket.error: [Errno 11] Resource temporarily unavailable. Errno 11 correspond à EWOULDBLOCK, donc recv() abandonné car aucune donnée n'était prête à être lue.

Votre code ne semble pas nécessiter de sockets non bloquants car il y a une accept() en haut de la boucle while, et donc une seule connexion peut être gérée à la fois. Vous pouvez simplement supprimer l'appel à c.setblocking(0) et ce problème devrait disparaître.

14
mhawke