[英]Python TCP server accepts new socket, but never receives data
我已经走到尽头了-我无法弄清楚这一点。 我是Python的新手,正在编写TCP Server / Client应用程序。
服务器侦听连接,并产生一个线程来处理连接。 通讯非常简单-客户端建立连接,发送消息,服务器响应然后关闭连接(ala HTTP)
问题在于我下面的服务器代码根本无法始终从客户端接收任何数据。 服务器接受新连接,启动新线程,然后阻止.recv方法。
服务器监听器
class TCPListener(threading.Thread):
def __init__(self, ip = settings.BIND_IP, port = settings.BIND_PORT):
super(TCPListener, self).__init__()
self.daemon = True
self._port = port
self._ip = ip
self.stop = threading.Event()
self.stop.clear()
self.tcp_server_socket = socket(AF_INET, SOCK_STREAM)
self.tcp_server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.tcp_server_socket.setblocking(False)
self.tcp_server_socket.bind((self._ip, self._port))
def run(self):
# Listen for client connection requests
with lock:
utils.log_message("Listening for ledger messages on port {0}".format(self._port))
try:
self.tcp_server_socket.listen(5)
# List for managing spawned threads
socket_threads = []
# Non-blocking socket loop that can be interrupted with a signal/event
while True and not self.stop.is_set():
try:
client_socket, address = self.tcp_server_socket.accept()
# Spawn thread
client_thread = TCPConnectionThread(client_socket)
client_thread.start()
socket_threads.append(client_thread)
except Exception as e:
continue
# Clean up all the threads
for thread in socket_threads:
thread.join()
except Exception as e:
print("Could not bind to port: {0}".format(e))
finally:
self.tcp_server_socket.close()
服务器连接处理程序
class TCPConnectionThread(threading.Thread):
def __init__(self, socket):
super(TCPConnectionThread, self).__init__()
with lock:
utils.log_message("Spawning TCP Connection Thread from {0}".format(socket.getsockname()))
self._socket = socket
def run(self):
# Get message
message = ''
data = True
while data:
data = self._socket.recv(4096) #BLOCKS HERE 99% OF THE TIME
message+=data.decode()
with lock:
utils.log_message("Received message from {0}:\n{1}".format(self._socket.getsockname(), message))
self._socket.sendall(response)
self._socket.close()
处理来自我的客户端的连接的线程只是阻塞。 如果在该点上放置一个断点(socket.recv),它可能会接收到数据,但是如果我正常运行它,它将无限期地阻塞。 我不确定为什么调试它会影响它,也许会引入延迟? 我可以在Wireshark中看到客户端正在发送消息,而服务器会对其进行确认,但是从recv()永远不会返回它。
任何帮助将不胜感激。 我在最有可能是一个简单错误上浪费了太多时间。
self._socket.recv
是阻止调用。 它将阻塞,直到在套接字上接收到数据为止。 我认为问题是:
data = True
while data:
data = self._socket.recv(4096) #BLOCKS HERE 99% OF THE TIME
message+=data.decode()
服务器接收数据,但再次进入循环并等待其他数据。 退出循环的标准是什么? 如果客户端发送数据但未断开连接,则该循环将始终处于活动状态。 只有客户端断开连接,循环才会中断。
我相信您会让自己变得过于复杂。 请参阅Python Cookbook中的以下示例:
from socket import AF_INET, SOCK_STREAM, socket
from concurrent.futures import ThreadPoolExecutor
def echo_client(sock, client_addr):
'''
Handle a client connection
'''
print('Got connection from', client_addr)
while True:
msg = sock.recv(65536)
if not msg:
break
sock.sendall(msg)
print('Client closed connection')
sock.close()
def echo_server(addr):
print('Echo server running at', addr)
pool = ThreadPoolExecutor(128)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock, client_addr = sock.accept()
pool.submit(echo_client, client_sock, client_addr)
echo_server(('',15000))
至少这是:
while True:
msg = sock.recv(65536)
if not msg:
break
应该照顾您的封锁问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.