线程和tcp / ip连接问题

时间:2017-05-14 12:47:59

标签: python multithreading tcp-ip

我是python和线程的新手,所以请无动于衷。我试图在python中进行2人游戏。数据通过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)

它是我的发送/接收功能,由另外两个线程执行:

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) 

通常没有错误,我们可以玩,但每台计算机上只有一个播放器,所以我认为服务器不会发送数据。我将不胜感激任何帮助。

1 个答案:

答案 0 :(得分:1)

您当前情况的修复方法是将所有这些连接变量更改为可以迭代的const maximumSubArray = function(array) { return array.reduce(([acc, ans], x, i) => { ans = Math.max(0, ans + x); return [Math.max(acc, ans), ans]; }, [array[0],array[0]])[0]; }; cl(maximumSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4])); // 6 个连接。您可能希望构建一些定义其行为的容器类,因为并非所有客户端都相同(服务器客户端和播放器客户端)。这样您就不会受到声明的变量数量和可用线程的限制。 然后,一旦新客户端连接,您只需将其添加到数组中,迭代器将负责其余部分。

这是TCP / IP的常见问题,因为您始终必须与array客户端建立开放连接,这不仅会占用资源,而且由于TCP / IP是排队协议,因此它也可以设置如果任何客户端的连接速度较慢,则整个游戏返回。在练习中,你的游戏总是和连接最差的玩家一样迟钝。

你有几个选择。

  1. 您可以打开一个处理连接的线程。你的n帖子。它包含一组打开的连接数据,并将操作分配给其他线程。这不是最佳选择,因为您很快就会遇到supervisor,例如两个线程试图使用相同的数据。
  2. 您可以切换到UDP,这会使您的线程全开,因为没有持久连接。然后,您需要向每个客户端发送状态,一旦他们Race Conditions,您就可以删除数据。大多数游戏现在都在实施UDP,甚至是基于转向的游戏。
  3. Beej的指南可能是互联网上关于UDP / TCP和套接字控制理论最广泛的指南。 http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html

    还有Gaffer on Games,这也是一个很棒的资源。 http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/