Python套接字无法接收数据

时间:2011-12-17 16:37:32

标签: python sockets

我正在使用Python 3.2中的localhost套接字编写进程间通信,并在Windows上进行测试。这是一些带有服务器和客户端的测试代码,相互发送消息。奇怪的是,它在RuntimeError函数中引发的receive错误随机失败,大约在第5或第10个连接处。

#!/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)

但是,如果我在time.sleep(0.01)中取消注释client_function,或者我稍微更改了消息顺序,则没有错误。

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

1 个答案:

答案 0 :(得分:0)

这是因为server_function中的conn.shutdown(socket.SHUT_WR)。你需要的是socket.SHUT_RD,或者更好的是,完全摆脱shutdown()调用。