ファイルの画像にアクセスし、それらをエンコードし、サーバーに送信するプログラムを作成したいと思います。サーバーが画像をデコードしてファイルに保存することになっているよりも。画像のエンコード自体をテストしましたが、うまくいきました。そのため、問題はサーバーとクライアントの接続にあります。
サーバーは次のとおりです。
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
サーバーでは、リモートソケット(accept()
によって返される)を非ブロックモードに設定しています。つまり、読み取るデータがない場合、そのソケットのI/Oは例外によって直ちに終了します。
通常、サーバーとの接続を確立してから、クライアントが送信する画像データまでの期間があります。サーバーは、接続が受け入れられるとすぐにクライアントからデータを読み取ろうとしますが、まだ読み取るデータがない可能性があるため、c.recv()
は_socket.error: [Errno 11] Resource temporarily unavailable
_例外を発生させます。 Errno 11はEWOULDBLOCK
に対応しているため、読み取り可能なデータがなかったため、recv()
は中止されました。
Whileループの先頭にaccept()
があり、一度に1つの接続しか処理できないため、コードは非ブロッキングソケットを必要としないようです。 c.setblocking(0)
への呼び出しを削除するだけで、この問題は解決するはずです。