线程和tcp/ip连接问题

2024-09-01 18:29:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python和线程方面的新手,所以请不要在意。我想用python做两人游戏。数据通过tcp/ip协议(客户机-服务器体系结构)发送。在服务器上,我有三个线程。一个与一个用户通信,第二个与第二个线程通信,在第三个线程中,我得到了客户端从另外两个线程发送的数据。这些数据用于检查游戏是否结束。一切都很顺利。问题从现在开始。当游戏结束后,我想发送另一个数据到客户端。所以线程3需要向客户机发送数据,但另外两个线程仍在工作,它们仍然与客户机有连接。一般我不知道怎么做。我试图通过队列从第三个线程向其他线程发送信息,要求他们关闭连接。它是线程类代码:

class myThread(threading.Thread):
   def __init__(self, threadID, name, conn, conn2, kto, wartosc, 
wybor,kolejkaZadan,gracz1,gracz2):
       threading.Thread.__init__(self)
       self.threadID = threadID
       self.name = name
       self.conn = conn
       self.conn2 = conn2
       self.kto = kto
       self.wartosc = wartosc
       self.wybor = wybor
       self.kolejkaZadan = kolejkaZadan
       self.gracz1 = gracz1
       self.gracz2 = gracz2

       def run(self):
            if self.wybor == None:       
            toClient(self.conn,self.conn2,self.kto,self.wartosc,self.gracz1)
            else:
               while True:

                 data,kolejkaZwrotna = self.kolejkaZadan.get() // I receive data from two others threads
                 time.sleep(10)
                 dataKolejne,kolejkaZwrotna = self.kolejkaZadan.get() // I receive data from two others threads

                 if data is dataKolejne: // if end
                   tworzenieXmla(self.gracz1, self.gracz2)
                   odczytywanieXmla('itemGracza1',gracz1Otrzymane)

                   plik = open('Marcin.xml', 'rb')

                   czyZamknacConnection = True
                   kolejkaZwrotna.put(czyZamknacConnection) // send data to two others threads 

                   while True:
                      czescXmla = plik.read(10000)

                     #self.conn2.send(czescXmla)

这是我的send/receiv函数,由另外两个线程执行:

def toClient(conn, conn2, kto, wartosc,gracz):
 wordsBackup = None
 kolejkaZwrotna = queue.Queue() 

 while True:

    data = conn.recv(BUFFER_SIZE)

    if not data:
        break

    if kolejkaZwrotna.get() is True://receive form thread 3 
        conn2.close()
        print('closed')
        break

    if len(data)>7:
        print('WARNING', data)

    words = str(data.decode()).split()
    #print(words[0], words[1])

    if kto==1:
        conn2.send(data)


    if kto==2:
        conn2.send(data)

    kolejkaZadan.put(words[2],kolejkaZwrotna) // send to thread 3 
    xmlTablicaDoZapisu(str(int(words[0])),str(int(words[1])),str(int(words[2])),gracz) 

一般没有错误,我们可以玩,但只有一个球员在每台电脑上,所以我认为服务器不发送数据。如果有任何帮助,我将不胜感激。你知道吗


Tags: 数据selfsendtruedataifconn线程
1条回答
网友
1楼 · 发布于 2024-09-01 18:29:26

解决当前情况的方法是将所有这些连接变量都更改为可以迭代的array连接。您可能需要构建一些容器类来定义它们的行为,因为并非所有的客户端(服务器客户端和播放器客户端)都是相同的。这样,您就不受已声明的变量数量和可用线程的限制。 然后,一旦一个新的客户机连接起来,您只需将它添加到数组中,您的迭代器就会处理其余的事务。你知道吗

不过,这是TCP/IP的一个常见问题,因为您必须始终拥有到n客户端的开放连接,这不仅占用资源,而且由于TCP/IP是一个排队协议,因此如果任何客户端的连接速度较慢,它还可以使整个游戏返回。在实践中,你的游戏将永远是落后的球员与最坏的连接。你知道吗

你有几个选择。你知道吗

  1. 你可以有一个线程总是打开的处理连接。你的supervisor线程。它保存一组打开连接的数据,并将操作分配给其他线程。这不是最好的选择,因为您很快就会遇到Race Conditions,例如两个线程试图使用相同的数据。你知道吗
  2. 您可以切换到UDP,这将使线程完全开放,因为没有持久连接。然后您需要向每个客户机发送状态,一旦它们ACK,您就可以删除这些数据。大多数游戏实现UDP now'a'days,甚至基于回合的游戏。你知道吗

Beej的指南可能是互联网上关于UDP/TCP和套接字控制理论的最广泛的指南。 http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html

另外,游戏中还有一个教练,这也是一个很好的资源。 http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/

相关问题 更多 >