2

テストに使用するソケット ユーティリティのコレクションで使用するために、次の関数を作成しました。(それが重要な場合は、Python 2.7.3 を使用します。)selectライブラリをライブラリに取り込んだ主な理由は、応答を永遠に待つのではなく、タイムアウトを実装できるようにするためでした。私が見つけた問題は.recv()、ソケットのメソッドの最大サイズとして 64K を使用しているにもかかわらず、応答が 2048 文字で切り捨てられていることです。この切り捨ては、私が関与する前には起こりませんでしたselect。最大サイズをより高く設定すると、64K を喜んで通過し、さらにそれ以上になりました。

いくつかのオンライン リソースをselect調べたところ、受信したデータのサイズに関するこの明らかな上限に関する情報が見つかりました。つまり、それを変更する方法は言うまでもなく、それが存在するという情報はありません。この 2K の制限を克服する方法を誰か教えてもらえますか?

    ソケットのインポート、選択
    最大サイズ = 65535
    タイムアウト = 10

    def transientConnect (ホスト、ポート、sendData):
        エラー、応答 = False、''
        試す:
            sendSocket = socket.socket()
            sendSocket.connect((ホスト,ポート))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            if (gotData[0]):
                応答 = sendSocket.recv(MAXSIZE)
            そうしないと:
                エラー = 真
                response = '*** タイムアウト ***\nホストからの応答がありません。'
            sendSocket.close()
        例外、errText を除く:
            error,response = True,'*** ソケット エラー ***\n'+str(errText)
        return (エラー、応答)
4

2 に答える 2

3

TCP ソケットはバイトの双方向ストリームを提供しますが、下位レベルではパケットベースのプロトコル (IP) を介して実現されています。つまり、TCP/IP スタックが送信のためにストリームを分割する方法に応じて、各読み取りでストリームの任意のチャンクを受信できます (ただし、バイトはすべて順序どおりです)。

ここでの重要な点は、完全な「アプリケーション メッセージ」を取得するまでループで実行する必要があるということです。recv()Socket Programming HOWTOから引用するには:

ここで、ソケットの主要な障害に到達し、ネットワーク バッファsendを操作します。recvそれらの主な焦点はネットワークバッファの処理であるため、それらは必ずしもあなたが渡す(またはそれらから期待される)すべてのバイトを処理するとは限りません。一般に、関連するネットワーク バッファがいっぱいになると (send)、空になると (recv) 返されます。次に、処理したバイト数を示します。あなたのメッセージが完全に処理されるまで、再度彼らに電話するのはあなたの責任です。

ここに表示されているのは、何らかのデータが利用可能になるselectとすぐに、早期通知を提供することです。

お役に立てれば。

于 2013-01-24T17:15:24.373 に答える
1

修正され、テストされ、機能する機能:

    最大サイズ = 65535
    タイムアウト = 10
    def transientConnect (ホスト、ポート、sendData):
        エラー、応答 = False、''
        試す:
            sendSocket = socket.socket()
            sendSocket.connect((ホスト,ポート))
            sendSocket.send(sendData)
            gotData = select.select([sendSocket],[],[],TIMEOUT)
            if (gotData[0]):
                応答 = sendSocket.recv(MAXSIZE)
                True の間:
                    #データが到着し始めたら、タイムアウトを短くする
                    gotData2 = select.select([sendSocket],[],[],0.5)
                    場合 (gotData2[0]):
                        moreData = sendSocket.recv(MAXSIZE)
                        応答 += moreData
                    そうでなければ:休憩
            そうしないと:
                エラー = 真
                response = '*** タイムアウト ***\nホストからの応答がありません。'
            sendSocket.close()
        例外、errText を除く:
            error,response = True,'*** ソケット エラー ***\n'+str(errText)
        return (エラー、応答)

于 2013-01-25T01:44:07.830 に答える