我正在使用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)
,或者如果我改變的消息整理了一下。
有沒有辦法讓它工作,而不用隨意等待,並允許任意協議?
有一個有用的[socketserver](http://docs.python.org/py3k/library/socketserver.html)模塊,它使你的服務器代碼更加穩定和可讀。 – Kirill 2011-12-17 18:02:18