如何在 Python 中使用套接字处理多线程?
Posted
技术标签:
【中文标题】如何在 Python 中使用套接字处理多线程?【英文标题】:How to handle multithreading with sockets in Python? 【发布时间】:2021-09-26 05:12:07 【问题描述】:我目前正在处理一个需要让服务器同时处理多个客户端的问题。我有一个 server.py 文件和一个 client.py 文件。这是来自 server.py 的 sn-p:
connections = []
addresses = []
for c in connections:
c.close()
del connections[:]
del addresses[:] #clears anything pre-existing
while True:
try:
csock, address = s.accept() #takes in connection and stores info
s.setblocking(1) #prevents timeout
connections.append(csock)
addresses.append(address)
print(f"Connection from address has been established!")
except:
print("Error has occurred")
当我在终端中运行我的服务器然后使用客户端连接到它时。它的行为与我预期的一样,打印出Connection from ('192.168.1.84', 50824) has been established!
。
当我打开另一个终端并运行 client.py 来建立一个额外的连接时,什么也没有发生。也就是说,直到我关闭我的第一个客户端进程,然后服务器打印出来
Error occurred
Connection from ('192.168.1.84', 50826) has been established!
我可以看到这里发生了什么,但我对网络非常陌生,而且我在多线程方面不是很擅长,所以谁能给我一些关于正在发生的事情以及我可以做些什么的见解这些进程是否如我所料同时运行?
【问题讨论】:
总是将完整的错误消息(从单词“Traceback”开始)作为文本(不是截图,不是链接到外部门户)有问题(不是评论)。还有其他有用的信息。 第一次运行没有try/except
的代码,看看你到底得到了什么错误。下次至少使用except Exception as ex: print(ex)
以始终查看有关问题的更多信息。
这是您在服务器中的所有代码吗?错误可能表明它运行了更多的东西 - 一些 recv()
可能等待来自客户端和块服务器的数据 - 其他客户端可能无法连接到服务器。
如果你想和很多客户一起工作,那么在accept()
之后你应该使用thread
在单独的线程中运行代码——然后主线程可能会回到accept
并等待下一个客户。您应该可以在 Internet 上以多种语言找到它。
【参考方案1】:
在s.accept()
之后,您应该使用threading
在单独的线程中运行代码 - 该线程应该继续与客户端连接。同时主线程可能会回到s.accept()
等待下一个客户端。
带有一些额外设置的最小工作代码。
服务器:
import socket
import threading
import time
# --- functions ---
def handle_client(conn, addr):
print("[thread] starting")
# recv message
message = conn.recv(1024)
message = message.decode()
print("[thread] client:", addr, 'recv:', message)
# simulate longer work
time.sleep(5)
# send answer
message = "Bye!"
message = message.encode()
conn.send(message)
print("[thread] client:", addr, 'send:', message)
conn.close()
print("[thread] ending")
# --- main ---
host = '0.0.0.0'
port = 8080
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # solution for "[Error 89] Address already in use". Use before bind()
s.bind((host, port))
s.listen(1)
all_threads = []
try:
while True:
print("Waiting for client")
conn, addr = s.accept()
print("Client:", addr)
t = threading.Thread(target=handle_client, args=(conn, addr))
t.start()
all_threads.append(t)
except KeyboardInterrupt:
print("Stopped by Ctrl+C")
finally:
if s:
s.close()
for t in all_threads:
t.join()
客户端(用于测试)
import socket
# --- main ---
host = '0.0.0.0'
port = 8080
s = socket.socket()
s.connect((host, port))
print("Connected to the server")
message = "Hello"
print('send:', message)
message = message.encode()
s.send(message)
message = s.recv(1024)
message = message.decode()
print('recv:', message)
【讨论】:
非常有帮助!谢谢!以上是关于如何在 Python 中使用套接字处理多线程?的主要内容,如果未能解决你的问题,请参考以下文章