1

私はこのソケットサーバースクリプトを持っています、

import SocketServer
import shelve
import zlib

    class MyTCPHandler(SocketServer.BaseRequestHandler):
        def handle(self):
            self.words = shelve.open('/home/tipu/Dropbox/dev/workspace/search/words.db', 'r');
            self.tweets = shelve.open('/home/tipu/Dropbox/dev/workspace/search/tweets.db', 'r');

            param = self.request.recv(1024).strip()
            try:
                result = str(self.words[param])
            except KeyError:
                result = "set()"
            self.request.send(str(result))

    if __name__ == "__main__":
        HOST, PORT = "localhost", 50007
        SocketServer.TCPServer.allow_reuse_address  = True
        server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
        server.serve_forever()

そしてこの受信機、

from django.http import HttpResponse
from django.template import Context, loader
import shelve
import zlib
import socket


def index(req, param = ''):
    HOST = 'localhost'    
    PORT = 50007              
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.send(param)
    data = zlib.decompress(s.recv(131072))
    s.close()
    print 'Received', repr(data)
    t = loader.get_template('index.html') 
    c = Context({ 'foo' : data })
    return HttpResponse(t.render(c))

数百キロバイトの文字列を受信者に送信しています。私はそれの一部しか受け取らないことになります。文字列全体が送信されるように修正する方法はありますか?

編集:私が送信しようとしている文字列は、実際には418437文字です。しかし、ここにアイデアがあります。str(set)を使用してセットの文字列表現を送信しようとしているので、evalを使用してセットを再アセンブルできます。ソケットに完全なデータを送信させる方法、またはソケットが一度に送信できるように十分に圧縮する方法はありますか?zlibを使用してみましたが、ヘッダーエラーが繰り返し発生するため、圧縮データが完全に送信されません。これは、圧縮された文字列が不完全であることが原因です。

4

2 に答える 2

6

socket.recv(N)は、正確にNバイトが受信されることを保証しません。むしろ、Nは、1つのgulpで受信できる最大バイト数です(効率を上げるために、理想的には4096の小さな倍数である必要があります。ドキュメントが提案します)。

必要なすべてのバイトが得られるまで「受信を続ける」(ループして蓄積する)必要があります(プロトコルがその重要な値を伝達していないように見えます。プレフィックス長または送信終了時のターミネータ。ストリームソケットから暗黙的に抽出できる方法はありません)。

送信についても同様ですが、その場合は、代わりに必要なループを実行するsocket.sendallを使用できます。

于 2010-05-31T16:37:04.020 に答える
0

ピクルスモジュールを使用して、オブジェクトをソケットにシリアル化し、反対側にロードします。何かのようなもの:

    pkl_dict= pickle.dumps(THE_SET)
    mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    mysocket.connect((HOST, PORT))

    mysocket.send(pkl_dict)

    mysocket.close()
于 2012-08-28T16:51:30.373 に答える