RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1563591
Accepted
Nymos
Nymos
Asked:2024-01-28 04:47:14 +0000 UTC2024-01-28 04:47:14 +0000 UTC 2024-01-28 04:47:14 +0000 UTC

Python 服务器不想连接超过 1 个客户端

  • 772

所有程序员朋友早上好。我用Python给同学写了一个程序,用货币代替金钱。然而,连接到服务器时出现问题,因为只有一个客户端可以连接,尽管程序将 .net 的程序设置为“2” serversocket.listen(2)。一位朋友建议我尝试这个库threading,所以我现在尝试使用这个模块。

我的服务器如何工作: 当客户端连接时,服务器会为客户端生成一个唯一的 ID,并将初始得分值存储在字典中。然后,服务器等待来自客户端的指示金额和收件人 ID 的消息。服务器收到消息后,检查收件人是否存在于客户端的字典中。如果是,则服务器更新发送者和接收者的帐户,并将有关新帐户的信息发送给客户端。如果收件人不存在,服务器会发送错误消息。

客户端代码:

该代码是程序的客户端部分,通过套接字连接到服务器,并通过 TCP 连接与其进行交互。客户端在连接时从服务器接收一个唯一的 ID,之后您可以向服务器发送请求,指示点数和接收者 ID。为了响应请求,服务器处理数据,更改发送者和接收者的点数,然后发送包含发送者和接收者的更新余额的响应。

当您输入 时quit,客户端会将此消息发送到服务器并关闭连接。

目标:确保只有两个客户端可以同时连接到服务器,至少目前是这样。此外,还应对程序进行更改以优化其性能和稳定性,以便服务器不会频繁崩溃或关闭。但我的首要目标是理清客户端连接!预先感谢愿意帮助我的人!

服务器代码:

import socket
import random

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = "localhost" 
port = 12345 
server_socket.bind((host, port))

server_socket.listen(2)

print("Сервер запущен на порту", port)

clients = {}

def handle_client(client_socket, client_address):
    id_value = str(random.randint(100000, 999999))
    clients[id_value] = 100  

    client_socket.send(id_value.encode())

    while True:
        data = client_socket.recv(1024).decode()
        print("Получено от клиента:", data)

        if data == "quit":
            break


        amount, recipient_id = data.split(",")
        amount = int(amount)

   
        if recipient_id in clients:
    
            sender_score = clients[id_value]
            sender_score -= amount
            clients[id_value] = sender_score

            
            recipient_score = clients[recipient_id]
            recipient_score += amount
            clients[recipient_id] = recipient_score

           
            response = "Ваши очки: {}\nСчет получателя: {}".format(sender_score, recipient_score)
            client_socket.send(response.encode())
        else:
            error_msg = "Неверный идентификатор получателя"
            client_socket.send(error_msg.encode())

   
    del clients[id_value]

  
    client_socket.close()

while True:
   
    client_socket, client_address = server_socket.accept()
    print("Установлено соединение с клиентом", client_address)

   
    handle_client(client_socket, client_address)

客户端代码:

import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Подключение к серверу
host = "localhost" 
port = 12345 
client_socket.connect((host, port))

client_id = client_socket.recv(1024).decode()

print("Ваш id:", client_id)

while True:
    amount = input("Введите количество очков для отправки ('quit' для выхода): ")
    if amount == "quit":
        client_socket.send(amount.encode())
        break

    recipient_id = input("Введите id получателя: ")

    data = "{},{}".format(amount, recipient_id)
    client_socket.send(data.encode())

    response = client_socket.recv(1024).decode()
    print(response)

client_socket.close()
python
  • 2 2 个回答
  • 90 Views

2 个回答

  • Voted
  1. Best Answer
    Nymos
    2024-01-28T19:11:53Z2024-01-28T19:11:53Z

    我能够使用 解决我的问题threading。我用它来同时处理多个客户。当客户端连接到我的服务器时,会创建一个新线程来处理与该客户端的交互,从而允许服务器并行处理其他客户端。

    但是,我想立即警告您! 如果您想使用我的方法,那么您需要考虑到,虽然该库threading允许您同时处理多个客户端,但它也会增加服务器的负载!

    现在我将尝试妥善组织和管理流程。如果您写下有关如何做得更好的建议,我将不胜感激。

    服务器现在是什么样子:

    import socket
    import random
    import threading
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    host = "localhost"
    port = 12345
    server_socket.bind((host, port))
    
    server_socket.listen(2)
    
    print("Сервер запущен на порту", port)
    
    clients = {}
    lock = threading.Lock()
    
    def handle_client(client_socket, client_address):
        id_value = str(random.randint(100000, 999999))
    
        with lock:
            clients[id_value] = 100
    
        client_socket.send(id_value.encode())
    
        while True:
            data = client_socket.recv(1024).decode()
            print("Получено от клиента:", data)
    
            if data == "quit":
                break
    
            if data == "/balance":
                with lock:
                    response = "Ваши очки: {}".format(clients[id_value])
                    client_socket.send(response.encode())
            elif data.startswith("/trade"):
                _, recipient_id, amount = data.split()
                amount = int(amount)
    
                with lock:
                    if recipient_id in clients and amount <= clients[id_value]:
                        sender_score = clients[id_value]
                        sender_score -= amount
                        clients[id_value] = sender_score
    
                        recipient_score = clients[recipient_id]
                        recipient_score += amount
                        clients[recipient_id] = recipient_score
    
                        response = "Очки успешно отправлены"
                        client_socket.send(response.encode())
                    else:
                        response = "Ошибка при отправке очков"
                        client_socket.send(response.encode())
            else:
                response = "Неверная команда"
                client_socket.send(response.encode())
    
        with lock:
            del clients[id_value]
    
        client_socket.close()
    
    def start_server():
        while True:
            client_socket, client_address = server_socket.accept()
            print("Установлено соединение с клиентом", client_address)
    
            client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
            client_thread.start()
    
    start_server()
    

    这就是客户端代码现在的样子:

    import socket
    
    host = "localhost"
    port = 12345
    
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((host, port))
    
    client_id = client_socket.recv(1024).decode()
    print("Подключено к серверу. Ваш идентификатор:", client_id)
    
    while True:
        command = input("Введите команду: ")
    
        if command.lower() == 'quit':
            client_socket.send('quit'.encode())
            break
        elif command.lower() == '/balance':
            client_socket.send('/balance'.encode())
            response = client_socket.recv(1024).decode()
            print("Ваши очки:", response)
        elif command.startswith('/trade'):
            _, recipient_id, amount = command.split()
            trade_command = "/trade {} {}".format(recipient_id, amount)
            client_socket.send(trade_command.encode())
            response = client_socket.recv(1024).decode()
            print(response)
        else:
            print("Неверная команда")
    
    client_socket.close()
    
    • 0
  2. eri
    2024-01-28T19:23:00Z2024-01-28T19:23:00Z

    使用框架,而不是裸露的套接字。例如,最低标准

    https://docs.python.org/3/library/socketserver.html

    线程服务器同时处理阻塞的事情,来自文档的示例:

    import socket
    import threading
    import socketserver
    
    class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    
        def handle(self):
            data = str(self.request.recv(1024), 'ascii')
            cur_thread = threading.current_thread()
            response = bytes("{}: {}".format(cur_thread.name, data), 'ascii')
            self.request.sendall(response)
    
    class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
        pass
    
    def client(ip, port, message):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
            sock.connect((ip, port))
            sock.sendall(bytes(message, 'ascii'))
            response = str(sock.recv(1024), 'ascii')
            print("Received: {}".format(response))
    
    if __name__ == "__main__":
        # Port 0 means to select an arbitrary unused port
        HOST, PORT = "localhost", 0
    
        server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
        with server:
            ip, port = server.server_address
    
            # Start a thread with the server -- that thread will then start one
            # more thread for each request
            server_thread = threading.Thread(target=server.serve_forever)
            # Exit the server thread when the main thread terminates
            server_thread.daemon = True
            server_thread.start()
            print("Server loop running in thread:", server_thread.name)
    
            client(ip, port, "Hello World 1")
            client(ip, port, "Hello World 2")
            client(ip, port, "Hello World 3")
    
            server.shutdown()
    
    • -1

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5