4

ソケットを介して接続を受け取り、pngファイルを保存するpythonでテストサーバーを作成しました。しかし、ファイルの名前、それを送信したユーザーなど、他のデータをサーバーに渡したいのですが、データを受信するには、バッファで読み取っているバイト数を通知する必要があるため、これはできません。

構造体を使用してすべてのデータをパックする例がいくつかありますが、画像ごとにサイズが異なり、受け取るファイルごとに異なるため、単純に構造体形式を作成することはできません。

これは私がこれまで取り組んできたことです:

サーバ

import socket
import os
import sys

FilePath = os.path.realpath(os.path.dirname(sys.argv[0]))

s = socket.socket()
s.bind(("localhost",8000))
s.listen(5) #Tipo, 5 conexoes no maximo {ao mesmo tempo}

i=0
name = 'file_'
while (True):
    sc, address = s.accept()
    name = 'file_%s' % i
    f = open(os.path.join(FilePath,'server_received/%s.png'% name) ,'wb') #open as binary data
    i=i+1
    # receives and writes the file
    l = sc.recv(1024)
    while (l):
        f.write(l)
        l = sc.recv(1024)
f.close()


sc.close()
s.close()

クライアント

class SendToServer(Thread):
    def __init__(self, queue, *args, **kwargs):
        Thread.__init__(self)
        self.queue = queue
        self.args = args
        self.kwargs = kwargs

    def run(self):
        try:
            while not self.queue.empty():
                s = socket.socket()
                s.connect((HOST,PORT))
                file_path = self.queue.get()
                file = open(file_path,'rb')
                s.send(file_path)
                l = file.read(1024)
                while l:
                    s.send(l)
                    l = file.read(1024)
                self.queue.task_done()
                s.close()
                print u"Enviado"
        except:
            print u"Sem conexao"

        #This i Use when I call the Thread:
        sync= SendToServer(queue)
        sync.run()

上記のコードはうまく機能していますが、ファイル以外のデータを送信するにはどうすればよいですか? (バイナリデータ)

4

3 に答える 3

4

「漬物」を見たことがありますか。pickle を使用すると、辞書などのオブジェクトを作成すると、オブジェクトをシリアル化できます。

    imageDict = {'imageFile': image, 'user': userName, 'fileName': file}

    pickleData = pickle.dumps(imageDict)

    s.send(pickleData)

サーバー上でデータを unpickle できるようになりました。

l = sc.recv(1024)

imageDict = pickle.dumps(l)

すべてのデータが受信されるまで待っている限り、クライアント側で作成したものと同じような辞書ができているはずです。

インタプリタでの例:

>>> import pickle
>>> data = {'mac':4, 'mid':5}
>>> data
{'mac': 4, 'mid': 5}
>>> dataPickle = pickle.dumps(data)
>>> dataPickle
"(dp0\nS'mac'\np1\nI4\nsS'mid'\np2\nI5\ns."
>>> unpick = pickle.loads(dataPickle)
>>> unpick
{'mac': 4, 'mid': 5}
>>>
于 2013-10-23T23:23:49.613 に答える
0

marshal( http://docs.python.org/2/library/marshal.html#module-marshal )を使用して取得しました。

そのため、すべてのデータ (ユーザー名、file_name、バイナリ ファイル) を含む dict を作成し、それをファイルに保存し (マーシャルはそれを行います)、すべてのバイナリ ファイルをサーバーに転送しました。

クライアント:

    while not self.queue.empty():
        try:
            s = socket.socket()
            s.connect((HOST,PORT))
        except:
            print "connection error"
            break
        file_path = self.queue.get()
        file = open(file_path,'rb')
        dados = ['User',
                'someothertext',
                file_path,
                file.read()
                ]
        temp = open(os.path.join(SaveDirectory,'temp'),'wb')
        marshal.dump(dados,temp)
        temp.close()
        file = open(os.path.join(SaveDirectory,'temp'),'rb')
        l = file.read(1024)
        while l:
            try:
                s.send(l)
                l = file.read(1024)
            except:
                print "error while sending"
                break


        temp.close()
        file.close()

        os.remove(os.path.join(SaveDirectory,'temp'))

        self.queue.task_done()

        s.close()
        print u"OK"

サーバ:

#coding: utf-8
import socket
import os
import sys
import marshal
FilePath = os.path.realpath(os.path.dirname(sys.argv[0]))

s = socket.socket()
s.bind(("localhost",8000))
s.listen(5) #Tipo, 5 conexoes no maximo {ao mesmo tempo}

i=0
nome = 'file_'
while (True):
    sc, address = s.accept()
    nome = 'file_%s' % i
    temp = open(os.path.join(FilePath,'server_received/%s'% nome) ,'wb')
    i=i+1
    l = sc.recv(1024)
    while (l):
        temp.write(l)
        l = sc.recv(1024)
    temp.close()
    temp = open(os.path.join(FilePath,'server_received/%s'% nome) ,'rb') #abrir como binario
    #Here I can unpack my dictionary.
    dados = marshal.load(temp)
    temp.close()
    #removing the file I received
    os.remove(os.path.join(FilePath,'server_received/%s'% nome))
    print dados[0], dados[1], dados[2]
    arq  = open(os.path.join(FilePath,'server_received/%s'% dados[2].split('\\')[-1]),'wb')
    arq.write(dados[3])
    arq.close()


sc.close()
s.close()
于 2013-10-25T00:51:58.967 に答える