当前位置: 首页 > 知识库问答 >
问题:

Python将两个客户端连接到一个服务器会导致第一个客户端中断

鲜于光赫
2023-03-14

我试图创建一个简单的python聊天界面,但是当两个客户端连接到服务器时,第一个客户端控制台会尽快打印空白,并导致最大递归深度错误,而第二个客户端仍然可以正常工作。服务器代码只在非空时发送数据,所以我不确定它为什么会这样做。

服务器代码:

import socket
from threading import Thread
from socketserver import ThreadingMixIn

class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print("[+] New thread started for "+ip+": "+str(port))

    def run(self):
        while True:
            data = conn.recv(1024).decode()
            if not data: break
            if data == "/exit":
                print("Connection for "+ip+" closed.")
                data = "Connection closed."
                conn.send(data.encode())
                break
            else:
                print("received data: ", data)
            if data != " ":
                conn.send(data.encode())
        print("connection "+ip+" force closed.")

TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(4)
    (conn, (ip,port)) = tcpsock.accept()
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

客户代码:

import socket
import threading
from threading import Thread

TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024

name = str(input("Input username: "))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

def recv():
    while True:
        data = s.recv(BUFFER_SIZE).decode()
        if not data: break
        print(data)
    recv()

def send():
    message = str(input())
    if message != "/exit":
        message = name + ": " + message
    s.send(message.encode())
    send()

if __name__ == "__main__":
    Thread(target = recv).start()
    Thread(target = send).start()

错误出现在客户机代码的第19行(接收和打印服务器发送的任何数据),如有任何帮助,将不胜感激。

共有1个答案

曾修真
2023-03-14

最可能的原因是发送和接收例程中的递归,我将它们改为循环。

def recv():
    while True:
        data = s.recv(BUFFER_SIZE).decode()
        if not data: break
        print(data)

def send():
    while True:
        message = str(input())
        if message != "/exit":
            message = name + ": " + message
        s.send(message.encode())

这里给出了关闭这些线程的解决方案:有没有办法在Python中杀死线程?

但是在这个场景中,没有必要在客户端的单个线程中运行发送和接收。

编辑:我再次仔细阅读你的代码。在客户端中,您将发送和接收方法作为线程启动。发送线程不会在线程中为其消息字符串获取任何输入,因为您循环它,它会向服务器发送空消息,或者(在我的情况下)以错误退出。

 类似资料:
  • 问题内容: 我正在使用RMI编写密码系统的原型。 我有一个问题,因为当我启动两个客户端时,它们从OneTimePad类的服务器中的一个对象获得了响应。 因此客户端A获取为客户端b保留的密钥,由于特定的算法,这种情况不会发生。 服务器仅向客户端发送E和N变量(例如在RSA中),因此我无法序列化OneTimePad对象并通过网络发送它(因为它将具有所有密钥)。 如何为每个客户端创建OneTimePad

  • 我正在开发一个具有多个客户端的标准java RMI服务器。这些客户机有一个菜单,在那里他们可以调用服务器为他们做各种事情。 一种方法涉及一个队列,他们可以在其中将作业发送到队列并等待它得到处理。RMI服务器自动为所有客户端处理线程,但当涉及到此方法和队列时,我如何阻止此请求,例如: 首先调用客户端1,然后再调用客户端2(此处客户端1应首先从服务器接收消息,客户端2应等待服务器处理客户端1请求所需的

  • 如何处理多个客户端连接到一个服务器?我有这个logserver.java 和一个嵌入式applet,其中包含如下所示的部分代码,例如 现在的问题是,如果我在服务器上运行“Java日志服务器”,它将打开应用程序并等待输入流,如果我打开我的站点,它将开始流日志。但如果我使用其他计算机/网络再打开一个站点,第二个站点不会记录流。似乎是因为第一个仍然绑定到端口5000。 我该怎么处理?socket实际上是

  • 编辑2:我切换到,并用包装客户端工厂,这样设备就可以很好地到达后端。但是当后端发回一些东西时,我会得到错误的出站套接字,客户机套接字死亡。我认为这是因为后端没有正确路由消息所必需的头。如何捕获此信息?我的配置类如下:

  • 我有一个包含10个微服务的微服务架构,每个微服务提供一个客户端。在由微服务团队管理/控制的客户机内部,我们只接收参数并将它们传递给一个通用http调用程序,该调用程序接收endpoint和N个params,然后进行调用。所有微服务都使用http和web api(我猜技术并不重要)。 对于我来说,作为微服务团队提供一个客户是没有意义的,应该是消费者的责任,如果他们想创建一些抽象或者直接调用它是他们的

  • 从我的应用程序中,我需要配置多个需要连接到单个服务器的客户端连接。为此,我使用Application Context BeanFactory创建了可变数量的bean,具体取决于我配置了多少客户端。这是2个客户端的代码: 这是我的工厂方法: 当我运行程序时,两个客户端都连接到我的服务器。然而,一旦服务器将其第一个有效负载发送到每个客户端,我就会得到以下异常(每个客户端一个): 这个想法是数据将被读取