2011-12-17 9 views
1

私は、Python 3.2でlocalhostソケットを使用してプロセス間通信を作成し、それをWindows上でテストしています。ここには、サーバーとクライアントのテストコードがあり、メッセージをお互いに送信しています。不思議なことに、receive関数で発生したRuntimeErrorエラーでランダムに失敗し、5番目または10番目の接続のどこかで発生します。Pythonソケットがデータを受け取ることができません

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import socket 
import pickle 
import time 
import logging 
from multiprocessing import Process 

def receive(conn): 
    def ensure_receive(length): 
     parts = [] 
     received = 0 
     while received < length: 
      chunk = conn.recv(length - received) 
      if not chunk: 
       raise RuntimeError("Connection broken") 
      parts.append(chunk) 
      received += len(chunk) 
     return b''.join(parts) 
    lengthString = ensure_receive(8) 
    serialized = ensure_receive(int(lengthString)) 
    return pickle.loads(serialized) 

def send(conn, message): 
    def ensure_send(message): 
     sent = 0 
     while sent < len(message): 
      sent += conn.send(message[sent:]) 
#   logging.warning("Now sending") 
    serialized = pickle.dumps(message, 1) 
    messageLength = len(serialized) 
    ensure_send("{:8}".format(messageLength).encode('Latin-1')) 
    ensure_send(serialized) 

def client_function(clientLimit): 
    for index in range(1, clientLimit + 1): 
     print ("Client", index) 
     try: 
      conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      conn.connect(('localhost', 12333)) 
      send(conn, list(range(100000))) 
      message = receive(conn) 
      send(conn, list(range(100))) 
#   time.sleep(0.01) 
      conn.shutdown(socket.SHUT_WR) 
      conn.close() 
     except Exception: 
      logging.exception("Socket error in client") 

def server_function(clientLimit): 
    newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    newSocket.bind(('localhost', 12333)) 
    newSocket.listen(16) 
    for _ in range(clientLimit): 
     (conn, address) = newSocket.accept() 
     time.sleep(0.01) 
     message = receive(conn) 
     send(conn, list(range(10))) 
     message = receive(conn) 
     conn.shutdown(socket.SHUT_WR) 
     conn.close() 

def test(clientLimit): 
    server = Process(target = server_function, args = (clientLimit,)) 
    server.start() 

    time.sleep(1) 
    client = Process(target = client_function, args = (clientLimit,)) 
    client.start() 

    client.join() 
    server.join() 

if __name__ == "__main__": 
    test(100) 

はしかし、そこに私はclient_functiontime.sleep(0.01)コメントを解除した場合にエラーではないか、私は少しメッセージの順序を変更した場合。

ランダムウェイトを入れずに任意のプロトコルを使用できるようにする方法はありますか?

+0

便利な[socketserver](http://docs.python.org/py3k/library/socketserver.html)モジュールは、サーバーコードをより安定して読みやすくします。 – Kirill

答えて

0

server_functionのconn.shutdown(socket.SHUT_WR)が原因です。あなたが必要とするのはsocket.SHUT_RDで、それ以上はシャットダウン()呼び出しを一切取り除いたほうが良いでしょう。

+0

ありがとうございます。シャットダウンを一切削除しても効果はありませんでしたが、SHUT_RDに変更しても問題ありませんでした。 – Kolmar

関連する問題