2011-12-17 163 views
1

我正在使用Python 3.2中的localhost套接字编写进程间通信并在Windows上测试它。以下是一些带有服务器和客户端的测试代码,相互发送消息。奇怪的是,它随机失败,RuntimeError错误,在receive函数中提出,在第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_function取消注释time.sleep(0.01),或者如果我改变的消息整理了一下。

有没有办法让它工作,而不用随意等待,并允许任意协议?

+0

有一个有用的[socketserver](http://docs.python.org/py3k/library/socketserver.html)模块,它使你的服务器代码更加稳定和可读。 – Kirill 2011-12-17 18:02:18

回答

0

这是因为你的server_function中的conn.shutdown(socket.SHUT_WR)。你需要的是socket.SHUT_RD,或者更好的是,根本不需要shutdown()调用。

+0

谢谢。根本没有帮助,但将其更改为SHUT_RD完成了这项工作。 – Kolmar 2011-12-17 17:57:36