我正在用 Python 编写一个多线程套接字应用程序。
这是我所拥有的一些基本骨架代码:
import socket, threading, time
class listener:
def __init__(self):
# Create a local listener socket
self.socket = socket.socket(AF_INET, SOCK_STREAM)
# Set options
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def start(self):
# Start listening for incoming connections in a loop. As connections
# come in, start new threads and accept/work with them.
self.socket.bind(('',1001)) # Bind to all addresses
while (True):
self.socket.listen(1) # blocks until a new connection is available
newSocket, addr = self.socket.accept() # Accept connection
thisConnThread = threading.Thread(target=server().runServer, args=( newSocket, addr ) )
thisConnThread.start() # call the connection handler on a new thread
# now return and listen for more connections.
class server:
def RunServer(self, socket, addr):
socket.write("Hello world!\n")
# Create a thread to listen for input from the client
thisListenThread = threading.Thread(target=self.RunServer_Listener, args=(socket.) )
thisListenThread.start()
# To demonstrate async - print a value every so many seconds - this
# needs to happen separately from the listener.
for i in range(0,100):
socket.write("Checkpoint!\n")
time.sleep(60)
socket.write("Your time is UP! Bye!\n")
socket.shutdown(socket.SHUTDOWN_RDWR) # close the connection
def RunServer_Listener(self, socket):
while (True):
inData = socket.read(4096) # blocks until data arrives
if not inData:
break # connection must be closed
socket.write("You wrote: %s\n" % inData)
在这种情况下,我期望发生的是,每次连接进入时,server
都会创建一个新的实例,并产生一个新的线程来运行它。
换句话说,thisConnThread = threading.Thread(target=server().runServer, args=( newSocket, addr ) )
对我来说应该是创建一个新实例,server
然后执行其中包含的函数。
我设置了一个单独的监听线程,因为在实际的服务器上,服务器可能需要随时向客户端发送数据,但它也需要随时响应客户端。由于 read() 阻塞直到数据可用,所以创建一个侦听线程来等待来自客户端的输入然后处理它对我来说是有意义的,但是主连接线程仍然可以做它需要做的事情并写入客户端独立于听者。
如果我与该服务器有一个连接,则可以完全按预期工作。
但是,如果我将第二个客户端连接到服务器,就会开始发生奇怪的事情。最重要和最令人担忧的是,如果我在第二个实例的客户端中输入,有时回复会转到第二个实例,有时会转到第一个实例,反之亦然。就好像 write() 操作正在做某种循环的事情——它交替地进入每个实例。
对于这个练习,真的不需要像一个活动连接列表一样保留。这可能适用于以后或更高级的项目,但就目前而言,客户端只是在服务器上度过他们的时间然后离开,服务器没有任何理由与其他连接进行交互。
我确定我在这里遗漏了一些东西,也许我的线程实现是错误的,或者我对套接字的使用完全错误。无论哪种方式,是否有人对如何使与服务器的连接完全相互独立有一些建议?