我试图找出一个多线程问题,两个客户端在运行ping服务器的同时永远运行,同时服务器不断回送消息。
在我发现一个客户端/服务器如何能够来回回显之后,我研究了多线程。
当我添加第二个客户端时,它将收到第一个客户端的最后一个输出。然后第二个客户端将重复与服务器进行回应,而第一个客户端永远不会收到消息,冻结它。
我被困在这几天,所以协助会很好。
无论如何,这是我用来测试的代码:
client A.朋友
import socket
import time
host = '127.0.0.1'
port = 2004
BUFFER_SIZE = 2000
tcpClientA = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientA.connect((host, port))
while True:
data = 'this is client A'
tcpClientA.send(data)
data2 = tcpClientA.recv(BUFFER_SIZE)
print " Client A received data:", data2
Clientb.py与客户端A相同,但带有b
server.朋友
import socket
import time
import thread
from threading import Thread
from SocketServer import ThreadingMixIn
BUFFER_SIZE = 1024
TCP_IP = '127.0.0.1'
TCP_PORT = 2004
tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
threads = []
def client(ip,port):
while True:
data = conn.recv(2048)
conn.send(data)
conn.close()
print "Server waiting"
tcpServer.bind((TCP_IP, TCP_PORT))
tcpServer.listen(4)
while True:
conn,addr=tcpServer.accept()
thread.start_new_thread(client,(conn,addr))
tcpServer.close()
你原来的client
函数没有使用传入的连接,而是在每个连接上覆盖的全局变量conn
。 ip
是传递给client
的连接。
由于您的服务器代码导入SocketServer,因此请使用它并简化代码。此代码将为每个客户端连接创建一个线程。 self.request
是套接字连接:
#!python2
import SocketServer
class Handler(SocketServer.StreamRequestHandler):
def handle(self):
while True:
data = self.request.recv(2048)
if not data: break
self.request.sendall(data)
server = SocketServer.ThreadingTCPServer(('',2004),Handler)
server.serve_forever()
您的客户端处理程序线程使用在主线程中分配的变量conn
中的套接字来接收数据并将数据发送到。基本上,您始终只使用创建的最后一个连接。
这通常在第二个客户端的输出中可见,在启动后立即显示:
Client B received data: this is client A
从这一点开始,两个客户端处理程序线程仅为客户端B提供服务,因为这部分client
函数...
data = conn.recv(2048)
conn.send(data)
...使用主线程中的conn
(套接字),每次新客户端连接到服务器时都会被覆盖:
conn, addr = tcpServer.accept()
客户端A此时等待来自服务器的数据:
data2 = tcpClientA.recv(BUFFER_SIZE)
但是,由于服务器中的两个客户端处理程序线程只监听并写入客户端B连接时创建的套接字,因此客户端A进程不再接收数据并无限期地等待某些进程阻塞。
您已经将相应的连接传递给客户端处理程序线程...
thread.start_new_thread(client, (conn, addr))
...你只需要使用它:
def client(ip,port):
while True:
data = ip.recv(2048) # receive from ip
ip.send(data) # send to ip
conn.close()