我试图与socket实现进程间通信。我有这个代码充当套接字服务器。收到消息后,服务器会将所有消息广播给其他连接的客户端。
from socket import AF_INET, gethostname, socket, SOCK_STREAM
import _thread as thread
clients = []
HOST = gethostname()
PORT = 33000
BUFFER_SIZE = 1024
ADDR = (HOST, PORT)
s = socket(AF_INET, SOCK_STREAM)
s.bind(ADDR)
def accept_client():
while True:
client, _ = s.accept()
clients.append(client)
print("Client accepted.")
thread.start_new_thread(handle_client, (client, ))
def handle_client(client):
while True:
message = client.recv(BUFFER_SIZE)
print("Incoming message: {}".format(message.decode('utf-8')))
broadcast(message)
def broadcast(message):
print("Broadcasting...")
for c in clients:
print("Broadcasting to {}".format(c))
c.send(message)
if __name__ == '__main__':
s.listen()
print("Listening...")
thread.start_new_thread(accept_client, ())
try:
while True:
pass
except KeyboardInterrupt:
print("Exited.")
exit(0)
这是我客户的课程。
from socket import AF_INET, gethostname, socket, SOCK_STREAM
import _thread as thread
class SocketClient:
buffer_size = 1024
def __init__(self, host=gethostname(), port=33000):
self.host = host
self.port = port
self.buffer_size = 1024
self.s = socket(AF_INET, SOCK_STREAM)
self.s.connect((self.host, self.port))
def bind_callback(self, callback, args=()):
thread.start_new_thread(self.receive, (callback, args))
def receive(self, callback, args):
while True:
try:
msg = self.s.recv(self.buffer_size).decode('utf-8')
callback(msg, *args)
except OSError as err:
self.close()
raise err
except NameError:
raise err
def send(self, msg):
try:
self.s.send(msg.encode('utf-8'))
except:
self.close()
def close(self):
self.send('{clientClose}')
self.s.close()
在我创建SocketClient
,对象的其他脚本中,脚本终止后有无限量的传入套接字(通过Python中的Ctrl + D)。服务器脚本(在收到传入套接字时打印尝试)会反复显示:
Incoming message:
Broadcasting...
Broadcasting to <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.1.1', 33000), raddr=('127.0.0.1', 44126)>
Broadcasting to <socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.1.1', 33000), raddr=('127.0.0.1', 44276)>
观察到似乎没有收到的消息。
我的假设是我未能正确关闭套接字连接(退出前)。怎么能实现这一目标?提前谢谢。
答案 0 :(得分:1)
调用client.recv(1024)
将阻止并返回1到1024字节,除非客户端断开连接,在这种情况下它将返回一个空的字节串:
def handle_client(client):
while True:
message = client.recv(BUFFER_SIZE)
if not message:
# client disconnected
break
...