Results 1 to 12 of 12

Thread: Reading problem at some (kind of random) point with QTcpSocket

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Reading problem at some (kind of random) point with QTcpSocket

    Hello,

    I have a bug in my application (or somewhere else) that uses
    QTcpServer, and I didn't figure out where it comes from.

    Here is the code of the method incomingConnection of the Server:

    Qt Code:
    1. class GameServer(QTcpServer):
    2.  
    3. def __init__(self, parent=None):
    4. self.games = []
    5. self.gameId = 0
    6.  
    7. super(GameServer, self).__init__(parent)
    8.  
    9. self.players = {}
    10. self.idList = [0]
    11.  
    12. self.startLck = QMutex()
    13.  
    14. self.startLck.lock()
    15.  
    16. def incomingConnection(self, socketId):
    17.  
    18. if len(self.idList) > 2:
    19. return
    20.  
    21. i = 0
    22. playerId = random.randint(10,300000)
    23.  
    24. while i < len(self.idList):
    25. if self.idList[i] == playerId:
    26. playerId = random.randint(10,300000)
    27. else:
    28. i += 1
    29.  
    30. self.idList[i-1] = playerId
    31. self.idList.append(0)
    32.  
    33. socket = QTcpSocket()
    34. if not socket.setSocketDescriptor(socketId):
    35. self.emit(SIGNAL("error(int)"), socket.error())
    36. return
    37.  
    38. self.players[playerId] = socket
    39.  
    40. reply = QByteArray()
    41. stream = QDataStream(reply, QIODevice.WriteOnly)
    42. stream.setVersion(QDataStream.Qt_4_6)
    43. stream.writeUInt16(0)
    44.  
    45. stream.writeUInt32(playerId)
    46.  
    47. stream.device().seek(0)
    48. stream.writeUInt16(reply.size() - SIZEOF_UINT16)
    49. socket.write(reply)
    50.  
    51. socket.waitForBytesWritten()
    52.  
    53. thread = GameServerThread(self, self.players, playerId, self.startLck)
    54. self.connect(thread, SIGNAL("finished()"),
    55. thread, SLOT("deleteLater()"))
    56. self.connect(thread, SIGNAL("debugPymagic"), self.DEBUG_GameServer)
    57.  
    58. thread.start()
    59.  
    60. if len(self.idList) == 3:
    61. self.startLck.unlock()
    To copy to clipboard, switch view to plain text mode 

    Here is the code of the thread that is started at incoming connection:

    Qt Code:
    1. class GameServerThread(QThread):
    2.  
    3. def __init__(self, parent, players, playerId, startLck):
    4. super(GameServerThread, self).__init__(parent)
    5.  
    6. self.startLck = startLck
    7.  
    8. self.players = players
    9. self.playerId = playerId
    10.  
    11. self.nextBlockSize = 0
    12.  
    13. def run(self):
    14.  
    15. self.startLck.lock()
    16. self.startLck.unlock()
    17.  
    18. socketToNotify = []
    19. for key, socket in self.players.items():
    20. if key != self.playerId:
    21. socketToNotify.append(socket)
    22. else:
    23. self.socket = socket
    24.  
    25. while self.socket.state() == QAbstractSocket.ConnectedState:
    26.  
    27. stream = QDataStream(self.socket)
    28. stream.setVersion(QDataStream.Qt_4_6)
    29.  
    30. self.nextBlockSize = 0
    31.  
    32. if self.socket.bytesAvailable() < SIZEOF_UINT16:
    33. while True:
    34. self.socket.waitForReadyRead(-1)
    35. if self.socket.bytesAvailable() >= SIZEOF_UINT16:
    36. break
    37.  
    38. self.nextBlockSize = stream.readUInt16()
    39.  
    40. if self.socket.bytesAvailable() < self.nextBlockSize:
    41. while True:
    42. self.socket.waitForReadyRead(-1)
    43. if self.socket.bytesAvailable() >= self.nextBlockSize:
    44. break
    45.  
    46. pos = QPoint()
    47.  
    48. action = stream.readUInt16()
    49. gameId = stream.readUInt16()
    50. playerId = stream.readUInt32()
    51.  
    52. params = []
    53.  
    54. if action in (Action.SetCardPos, Action.SetCardZone):
    55.  
    56. cardId = stream.readUInt32()
    57. params.append(Parameter(cardId, Parameter.UInt32))
    58.  
    59. if action == Action.SetCardPos:
    60. stream >> pos
    61. params.append(Parameter(pos, Parameter.Position))
    62.  
    63. elif action == Action.SetCardZone:
    64. cardName = stream.readQString()
    65. zone = stream.readUInt16()
    66.  
    67. params.append(Parameter(cardName, Parameter.String))
    68. params.append(Parameter(zone, Parameter.UInt16))
    69.  
    70. if cardName == "token":
    71. color = stream.readQString()
    72. power = stream.readUInt16()
    73. toughness = stream.readUInt16()
    74.  
    75. params.append(Parameter(color, Parameter.String))
    76. params.append(Parameter(power, Parameter.UInt16))
    77. params.append(Parameter(toughness, Parameter.UInt16))
    78.  
    79. else:
    80. print("GameSeverThread: Unknow action!")
    81. continue
    82.  
    83. else:
    84. print("GameSeverThread: action [%d] unhandled!" % action)
    85. continue
    86.  
    87.  
    88. for sck in socketToNotify:
    89. self.sendRequest(sck, action, gameId, playerId, params)
    To copy to clipboard, switch view to plain text mode 

    I use PyQt 4.8.1 with SIP 4.11.2 (and was experiencing the same
    problem with older versions) under python 3.1.2.

    To summarize, it's a client-server application, and the approach is a
    lot inspired from the multi-threaded example in the "Rapid GUI
    Programming With Python and Qt" book,
    with minor corrections to avoid packet shifting at reception (which is
    not related to the problem, as it was here before these corrections).

    The problem is that during execution the server seems to behave
    strangely at some point in time. I printed some information to monitor
    what happens, and I saw that
    at the beginning the server receives packets correctly (the size of
    packets is around 30 bytes, and I use, like in the book example, a
    quint16 at the beginning of each block to store the size of data).
    But at some point (which seems to be random), the server gets packets
    that seems corrupted, where the quint16 read from the socket (which
    correspond to the "nextBlockSize") by the server (for processing the
    "nextBlock") is the value 0!
    The problem seems to be at the server (reception) side, because when I
    print the size written in the packet at the client side, all is ok.
    Besides, I always test the connection state, and there is no problem
    at this side.

    The emission of packets (at the client side) depends on the movement
    of a QGraphicsItem which is controlled by the mouse. Thus the
    throughput of sent network packets depends on the user which interact
    with the QGraphicsItems.

    Note that I have the same problem, either testing this application
    (client + server) on the same machine (connecting to localhost), or
    using two machines on the same LAN.

    Any help will be welcome. Don't hesitate to ask me more questions.

    Thanks in advance.
    Last edited by tuxiko; 29th November 2010 at 18:42.

Similar Threads

  1. Replies: 1
    Last Post: 7th April 2010, 16:26
  2. Problem with reading in data from a QTCPSocket
    By Denarius in forum Qt Programming
    Replies: 4
    Last Post: 24th April 2009, 08:54
  3. QTcpSocket writing reading problem
    By Misenko in forum Qt Programming
    Replies: 4
    Last Post: 15th October 2008, 07:27
  4. Reading non-ASCII lines from QTcpSocket via readLine()
    By joshtn in forum Qt Programming
    Replies: 1
    Last Post: 26th June 2008, 23:52
  5. Replies: 6
    Last Post: 8th January 2007, 10:24

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.