只有一个客户端在多个客户端的服务器中接收消息

Posted

技术标签:

【中文标题】只有一个客户端在多个客户端的服务器中接收消息【英文标题】:ONLY one client receive message in multiple client's server 【发布时间】:2021-12-12 18:29:17 【问题描述】:

我的目标是在客户端屏幕上打印来自函数result 的消息。但是只有一个客户端可以收到消息...


client.py部分在这里

def PlayGame(clientSocket, msg):
invalid = "NO!"
if ("/guess " in msg):
    msg1 = msg.split(" ")[1]
    print("Hi1\n")
    if msg1 == "true" or msg1 == "false":
        print("Hi11")
        clientSocket.send(msg1.encode())
        print(clientSocket.recv(1024).decode())
        print("!")
        return '1'

    else:
        clientSocket.send(invalid.encode())
        print(clientSocket.recv(1024).decode())
        print("2")
        return '2'
elif msg == "":
    return '2'
else:
    clientSocket.send(invalid.encode())
    print(clientSocket.recv(1024).decode())
    print("3")
    return '2'

def main(argv):
            msg=""
            while (PlayGame(clientSocket, msg)!=1):
                msg = input()

server.py 的任何部分

guess_box = []
guess = bool(random.randint(0, 1))
    def result(connectionSocket, guess_box,  addr, addr_l):
        a = 0
        if(guess_box[0] == guess_box[1]):
            msg = "Tie!!"
            connectionSocket.send(msg.encode())
            return '2'
        elif(guess_box[0] == guess):
            msg = "Player 1 Wins!"
            a+=1
            connectionSocket.send(msg.encode())
            return '2'
        elif(guess_box[1] == guess):
            msg = "Player 2 Wins!"
            a+=1
            connectionSocket.send(msg.encode())
            return '2'
    
    def TF(connectionSocket, var, guess_box, addr, addr_l):
        msg = connectionSocket.recv(1024).decode()
        print("recv:",msg)
        if(msg == 'true'):
            msg = 'True'
            var = str(var)
            msg = bool(msg == var)
            guess_box.append(msg)
            return 'ok'
        elif(msg == 'false'):
            msg = 'False'
            var = str(var)
            msg = bool(msg == var)
            guess_box.append(msg)
            return 'ok'
        else:
            print(msg)
            statement = "4002 Unrecognized message!!"
            connectionSocket.send(statement.encode())
            return 'again'
class ServerThread(threading.Thread):
    def __init__(self, client):
        threading.Thread.__init__(self)
        self.client = client

    def run(self):
    ...
    print("guess is:", guess)
    
                    while (len(guess_box) != 2):
                        TF(connectionSocket, guess, guess_box, addr, addr_l)
    
                    print("start")
                    result(connectionSocket, guess_box, addr, addr_l)
    ...

【问题讨论】:

请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。 一些问题:GameHallMsg'list' 执行return 1 和无效的'enter' 消息,而它应该而不是return 'wait'while(1): #waiting the other player 是一个没有意义的循环。 @Armali 我已经更新了代码并编写了预期的输出。再次感谢您的建议! 我认为问题是:第二个客户端输入命令/guess,收不到消息。 【参考方案1】:

仅关于您解决的一个问题:

在客户端屏幕上打印来自函数结果的消息。但是只有一个客户端可以接收到消息

问题来自为每个客户端使用不同的线程。第一个收到猜测的线程留在它的

                        while (len(guess_box) != 2):
                            print(guess_box)
                            TF(connectionSocket, guess, guess_box)

循环并等待另一条没有到来的消息。接收到第二个猜测的线程只将结果发送给它自己的客户端。

我认为在保持这种 d 线程化方法的同时解决此问题是不明智的。

我可以使用我实现的那些函数来改变我的代码结构吗?

这是server_runwhile True 循环的替代品,除了server_run 之外,不需要更改那些函数

        from select import select
        connections = []
        room_connection = 
        for reads in iter(lambda: select([serverSocket]+connections, [], [])[0], []):
            for ready in reads: # for each socket which select reports is readable
                if ready == serverSocket:   # it's the server socket, accept new client
                    connectionSocket, addr = serverSocket.accept()
                    connections.append(connectionSocket)# store the connection socket
                    while RecvFromClient(connectionSocket) == "NO": pass
                else:           # message (or disconnect) from a client
                    try: var = GameHallMsg(ready, ready, connections)
                    except socket.error: var = 'bye'
                    if var == 'bye':    # client finished, remove from list
                        connections.remove(ready)
                        ready.close()
                    elif var == 'wait': # store first player's connection
                        room_connection[current_rm_num.pop()] = ready
                    elif var == 'NO':
                        rtn_msg_4 = "4002 Unrecognized message"
                        ready.send(rtn_msg_4.encode())
                    elif var == 'jump':
                        readyroom = current_rm_num.pop()
                        # find and notify other player in the room
                        other = room_connection.pop(readyroom)
                        rtn_msg_2 = "3012 Game started. Please guess true or false"
                        other.send(rtn_msg_2.encode())
                        print("guess is:", guess)
                        # query and inform both players
                        guess_box = []
                        while TF(ready, True, guess_box) != 'ok': pass
                        while TF(other, True, guess_box) != 'ok': pass
                        result(ready, guess_box, ('', 0), [0])
                        result(other, guess_box, ('', 1), [0, 1])
                        room[readyroom] = 0

【讨论】:

我可以使用我实现的那些函数来改变我的代码结构吗?很抱歉我对线程不熟悉 如果那些函数中的错误得到纠正,即state的索引,RecvFromClient的索引是username.index,但@987654330 @ 是addr_l.index (在一个地方state被设置为房间号,否则它被用作计数器。) 感谢您回答我的疑问! Acutally 我已经在 github 上找到了我的问题的“解决方案”:github.com/yeeaayee/Computer_Network_Coursework/blob/master/… 但是我可以使用我现有的代码对上面的代码做同样的事情,只需纠正你提出的问题吗?再次感谢!!! 非常感谢您的帮助!!但是为什么是server_run 中的变化而不是ServerThread 中的run 中的变化呢? ServerThread 中的运行不是控制整个线程吗?很抱歉我最近才在其他课程中学习多线程..

以上是关于只有一个客户端在多个客户端的服务器中接收消息的主要内容,如果未能解决你的问题,请参考以下文章

异步接收来自服务器的消息

Java 网络编程:案例四:多个客户端群聊

服务器客户端发送/接收多个客户端

Java 网络编程案例三:多个客户端上传文件

为啥tcp服务器可以获取客户端的ip?

多播组客户端不从服务器接收消息