Results 1 to 12 of 12

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

  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 19:42.

  2. #2
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    During my tests I also get this error sometimes:

    *** glibc detected *** python3.1: free(): invalid next size (fast): 0x000000000567cd20 ***
    ======= Backtrace: =========
    /lib/libc.so.6(+0x774b6)[0x7f6c730ea4b6]
    /lib/libc.so.6(cfree+0x73)[0x7f6c730f0c83]
    /usr/lib/libX11.so.6(+0x4a2d4)[0x7f6c70daf2d4]
    /usr/lib/libX11.so.6(_XEventsQueued+0x37)[0x7f6c70dafd07]
    /usr/lib/libX11.so.6(XEventsQueued+0x6f)[0x7f6c70d9847f]
    /usr/lib/libQtGui.so.4(+0x26ac0c)[0x7f6c719b3c0c]
    /lib/libglib-2.0.so.0(g_main_context_check+0x25a)[0x7f6c6fee166a]
    /lib/libglib-2.0.so.0(+0x44023)[0x7f6c6fee2023]
    /lib/libglib-2.0.so.0(g_main_context_iteration+0x6c)[0x7f6c6fee245c]
    /usr/lib/libQtCore.so.4(_ZN20QEventDispatcherGlib13processE ventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0 x73)[0x7f6c71442193]
    /usr/lib/libQtGui.so.4(+0x26aa4e)[0x7f6c719b3a4e]
    /usr/lib/libQtCore.so.4(_ZN10QEventLoop13processEventsE6QFl agsINS_17ProcessEventsFlagEE+0x32)[0x7f6c71414a02]
    /usr/lib/libQtCore.so.4(_ZN10QEventLoop4execE6QFlagsINS_17P rocessEventsFlagEE+0xdc)[0x7f6c71414dec]
    /usr/lib/libQtCore.so.4(_ZN16QCoreApplication4execEv+0xbb)[0x7f6c71418ebb]
    /usr/lib/python3/dist-packages/PyQt4/QtGui.so(+0x509a3b)[0x7f6c7293aa3b]
    python3.1(PyEval_EvalFrameEx+0x57bf)[0x4620ff]
    python3.1(PyEval_EvalCodeEx+0x8a5)[0x463ea5]
    python3.1(PyEval_EvalCode+0x3b)[0x463fab]
    python3.1(PyRun_FileExFlags+0x138)[0x485f88]
    python3.1(PyRun_SimpleFileExFlags+0xd4)[0x4861a4]
    python3.1(Py_Main+0x939)[0x49a739]
    python3.1(main+0x1de)[0x41a7ee]
    /lib/libc.so.6(__libc_start_main+0xfe)[0x7f6c73091d8e]
    python3.1[0x41a549]
    ======= Memory map: ========
    00400000-0065d000 r-xp 00000000 fc:08 1589327 /usr/bin/python3.1
    0085c000-0085d000 r--p 0025c000 fc:08 1589327 /usr/bin/python3.1
    0085d000-008cf000 rw-p 0025d000 fc:08 1589327 /usr/bin/python3.1
    008cf000-008ef000 rw-p 00000000 00:00 0
    01fd2000-05e4a000 rw-p 00000000 00:00 0 [heap]
    7f6c54000000-7f6c54021000 rw-p 00000000 00:00 0
    7f6c54021000-7f6c58000000 ---p 00000000 00:00 0
    7f6c599ca000-7f6c599cb000 ---p 00000000 00:00 0
    7f6c599cb000-7f6c5a1cb000 rw-p 00000000 00:00 0
    7f6c5a1cb000-7f6c5a1cc000 ---p 00000000 00:00 0
    7f6c5a1cc000-7f6c5a9cc000 rw-p 00000000 00:00 0
    7f6c5a9cc000-7f6c5a9cd000 ---p 00000000 00:00 0
    7f6c5a9cd000-7f6c5b1cd000 rw-p 00000000 00:00 0
    7f6c5b1cd000-7f6c5b1ce000 ---p 00000000 00:00 0
    7f6c5b1ce000-7f6c5b9ce000 rw-p 00000000 00:00 0
    7f6c5b9ce000-7f6c5b9da000 r-xp 00000000 fc:08 133339 /lib/libnss_files-2.12.1.so
    7f6c5b9da000-7f6c5bbd9000 ---p 0000c000 fc:08 133339 /lib/libnss_files-2.12.1.so
    7f6c5bbd9000-7f6c5bbda000 r--p 0000b000 fc:08 133339 /lib/libnss_files-2.12.1.so
    7f6c5bbda000-7f6c5bbdb000 rw-p 0000c000 fc:08 133339 /lib/libnss_files-2.12.1.so
    7f6c5bbdb000-7f6c5bbe5000 r-xp 00000000 fc:08 133341 /lib/libnss_nis-2.12.1.so
    7f6c5bbe5000-7f6c5bde4000 ---p 0000a000 fc:08 133341 /lib/libnss_nis-2.12.1.so
    7f6c5bde4000-7f6c5bde5000 r--p 00009000 fc:08 133341 /lib/libnss_nis-2.12.1.so
    7f6c5bde5000-7f6c5bde6000 rw-p 0000a000 fc:08 133341 /lib/libnss_nis-2.12.1.so
    7f6c5bde6000-7f6c5bdfd000 r-xp 00000000 fc:08 133336 /lib/libnsl-2.12.1.so
    7f6c5bdfd000-7f6c5bffc000 ---p 00017000 fc:08 133336 /lib/libnsl-2.12.1.so
    7f6c5bffc000-7f6c5bffd000 r--p 00016000 fc:08 133336 /lib/libnsl-2.12.1.so
    7f6c5bffd000-7f6c5bffe000 rw-p 00017000 fc:08 133336 /lib/libnsl-2.12.1.so
    7f6c5bffe000-7f6c5c000000 rw-p 00000000 00:00 0
    7f6c5c000000-7f6c5c19e000 rw-p 00000000 00:00 0
    7f6c5c19e000-7f6c60000000 ---p 00000000 00:00 0
    7f6c60167000-7f6c6016f000 r-xp 00000000 fc:08 133337 /lib/libnss_compat-2.12.1.so
    7f6c6016f000-7f6c6036e000 ---p 00008000 fc:08 133337 /lib/libnss_compat-2.12.1.so
    7f6c6036e000-7f6c6036f000 r--p 00007000 fc:08 133337 /lib/libnss_compat-2.12.1.so
    7f6c6036f000-7f6c60370000 rw-p 00008000 fc:08 133337 /lib/libnss_compat-2.12.1.so
    7f6c60370000-7f6c60431000 rw-p 00000000 00:00 0
    7f6c60431000-7f6c60435000 r-xp 00000000 fc:08 1589184 /usr/lib/kde4/plugins/imageformats/kimg_xview.so
    7f6c60435000-7f6c60634000 ---p 00004000 fc:08 1589184 /usr/lib/kde4/plugins/imageformats/kimg_xview.so
    7f6c60634000-7f6c60635000 r--p 00003000 fc:08 1589184 /usr/lib/kde4/plugins/imageformats/kimg_xview.so
    7f6c60635000-7f6c60636000 rw-p 00004000 fc:08 1589184 /usr/lib/kde4/plugins/imageformats/kimg_xview.so
    7f6c60636000-7f6c60645000 r-xp 00000000 fc:08 1596406 /usr/lib/kde4/plugins/imageformats/kimg_xcf.so
    7f6c60645000-7f6c60844000 ---p 0000f000 fc:08 1596406 /usr/lib/kde4/plugins/imageformats/kimg_xcf.so
    7f6c60844000-7f6c60845000 r--p 0000e000 fc:08 1596406 /usr/lib/kde4/plugins/imageformats/kimg_xcf.so
    7f6c60845000-7f6c60846000 rw-p 0000f000 fc:08 1596406 /usr/lib/kde4/plugins/imageformats/kimg_xcf.so
    7f6c60846000-7f6c6084a000 rw-p 00000000 00:00 0
    7f6c6084a000-7f6c6084f000 r-xp 00000000 fc:08 1596408 /usr/lib/kde4/plugins/imageformats/kimg_tga.so
    7f6c6084f000-7f6c60a4e000 ---p 00005000 fc:08 1596408 /usr/lib/kde4/plugins/imageformats/kimg_tga.so
    7f6c60a4e000-7f6c60a4f000 r--p 00004000 fc:08 1596408 /usr/lib/kde4/plugins/imageformats/kimg_tga.so
    7f6c60a4f000-7f6c60a50000 rw-p 00005000 fc:08 1596408 /usr/lib/kde4/plugins/imageformats/kimg_tga.so
    7f6c60a50000-7f6c60a59000 r-xp 00000000 fc:08 1596410 /usr/lib/kde4/plugins/imageformats/kimg_rgb.so
    7f6c60a59000-7f6c60c59000 ---p 00009000 fc:08 1596410 /usr/lib/kde4/plugins/imageformats/kimg_rgb.so
    7f6c60c59000-7f6c60c5a000 r--p 00009000 fc:08 1596410 /usr/lib/kde4/plugins/imageformats/kimg_rgb.so
    7f6c60c5a000-7f6c60c5b000 rw-p 0000a000 fc:08 1596410 /usr/lib/kde4/plugins/imageformats/kimg_rgb.so
    7f6c60c5b000-7f6c60c60000 r-xp 00000000 fc:08 1589186 /usr/lib/kde4/plugins/imageformats/kimg_ras.so
    7f6c60c60000-7f6c60e5f000 ---p 00005000 fc:08 1589186 /usr/lib/kde4/plugins/imageformats/kimg_ras.so
    7f6c60e5f000-7f6c60e60000 r--p 00004000 fc:08 1589186 /usr/lib/kde4/plugins/imageformats/kimg_ras.so
    7f6c60e60000-7f6c60e61000 rw-p 00005000 fc:08 1589186 /usr/lib/kde4/plugins/imageformats/kimg_ras.so
    7f6c60e61000-7f6c60e65000 r-xp 00000000 fc:08 1596404 /usr/lib/kde4/plugins/imageformats/kimg_psd.so
    7f6c60e65000-7f6c61065000 ---p 00004000 fc:08 1596404 /usr/lib/kde4/plugins/imageformats/kimg_psd.so
    7f6c61065000-7f6c61066000 r--p 00004000 fc:08 1596404 /usr/lib/kde4/plugins/imageformats/kimg_psd.so
    7f6c61066000-7f6c61067000 rw-p 00005000 fc:08 1596404 /usr/lib/kde4/plugins/imageformats/kimg_psd.soAbandon[/QUOTE]

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    One suspicious thing I see is that you expect "nextBlockSize" bytes to come but then you read some amount of data which doesn't have to be the whole data that is to be read and your stream can easily fall out of sync. I don't know if that's the source of your problems but it might be. A much better approach is to design a data structure, implement serialization operators for it and stream the whole structure into the socket in one go on one end and read the whole structure in one go on the other end. Then you will be certain your stream will never fall out of sync because you can easily check if the stream read the structure properly by checking the stream's status. Also try simplifying your code, it's way overcomplicated, e.g. lines 32-36 of the last snippet can be rewritten as:

    python Code:
    1. while self.socket.bytesAvailable() < SIZEOF_UINT16:
    2. self.socket.waitForReadyRead(-1)
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  4. #4
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    I'm not sure I understand you correctly as I always wait for "nextBlockSize". Here is the simplified server code and below I show the results of my tests. It seems a weird exception is raised.


    Qt Code:
    1. ...
    2. while self.socket.state() == QAbstractSocket.ConnectedState:
    3.  
    4. self.nextBlockSize = 0
    5.  
    6. while self.socket.bytesAvailable() < SIZEOF_UINT16:
    7. self.socket.waitForReadyRead(-1)
    8.  
    9. print("Bytes available: %d" % self.socket.bytesAvailable())
    10. self.nextBlockSize = stream.readUInt16()
    11.  
    12. if self.nextBlockSize == 0:
    13. print("GameServer: Problem with QTcpSocket?!\n"
    14. "QDataStream status(): %d" % stream.status())
    15. return
    16.  
    17. while self.socket.bytesAvailable() < self.nextBlockSize:
    18. self.socket.waitForReadyRead(-1)
    19.  
    20. print("BlockSize: %d" % self.nextBlockSize)
    21. ...
    To copy to clipboard, switch view to plain text mode 

    I also print at the client side what it sends (it is represented below by the byte arrays and the lines "SIZE: x" -- in red color).
    The printed lines on the console are:

    ...
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x03\x84\x00\x00\x01\x9f'
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x03(\x00\x00\x01\xc7'
    SIZE: 22
    SIZE: 22

    Bytes available: 44
    BlockSize: 20
    Bytes available: 22
    BlockSize: 20
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x02\xd6\x00\x00\x01\xea'
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x02\x88\x00\x00\x02\x03'
    SIZE: 22

    Bytes available: 44
    BlockSize: 20
    Bytes available: 22
    BlockSize: 20
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x02=\x00\x00\x02\x1c'
    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x01\xe1\x00\x00\x02"'
    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x00\x96\x9d\x05w\xd2\x 90\x00\x00\x01\xc1\x00\x00\x01\xcd'

    Bytes available: 22
    GameServer: Problem with QTcpSocket?!
    QDataStream status(): 1

    (Note that the "SIZE:" lines are printed by the client GUI-thread whereas the byte arrays are printed by an independent client thread)

    So at the end it seems that I have read past the end of the stream (status == 1), but my code seems correct.
    However I just have caught this exception :

    ------------
    Error in sys.excepthook:
    TypeError: 'NoneType' object is not callable

    Original exception was:
    Traceback (most recent call last):
    File "/home/tuxico/Projets/PyMagic-git/pm_gameserver.py", line 92, in run
    TypeError: unorderable types: int() < NoneType()
    ------------

    and the faulting line is in the code above:

    Qt Code:
    1. while self.socket.bytesAvailable() < SIZEOF_UINT16:
    To copy to clipboard, switch view to plain text mode 

    What does it means?

    Thanks for all your patience.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    I think something might have deleted your socket.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

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

    One big problem I see is this:
    Qt Code:
    1. self.connect(thread, SIGNAL("finished()"), thread, SLOT("deleteLater()"))
    To copy to clipboard, switch view to plain text mode 

    What happens if you delete or comment that line?

  7. #7
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    By commenting this line it seems that my application does not crash easily good catch! (I will like to have more explanations)
    But the out of sync / corruption problem is not resolved (I also join another code extract below the logs) :

    Note: red color is used to distinguish what the client prints

    ...
    b'\x00\x14\x00\x00\x00@\x00\x00\xcf\x97\x04.\xb2\x d0\x00\x00\x05\xfa\x00\x00\x00\x00'
    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x00\xcf\x97\x04.\xb2\x d0\x00\x00\x06E\x00\x00\x00\x00'

    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x00\xcf\x97\x04.\xb2\x d0\x00\x00\x06q\x00\x00\x00F'

    Bytes available: 22
    GameServer: Bug of QTcpSocket?!
    QDataStream status(): 1
    ...

    --> the status seems to say that there has been a reading that has begun too soon :/

    And another log that show a corruption case:

    Notes:
    - at some point, I have moved a QGraphicsItem very quickly in order to generate a lot of network packets
    - the actions 2827 or 2828 are not valid numbers (valid ones are 0 and 1)
    - the repetition of 2827 and 2828 seems strange...

    ...
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03\xa4\x00\x00\x02K'
    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03?\x00\x00\x02D'

    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03\x11\x00\x00\x02\x03'

    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03!\x00\x00\x01\xa8'

    Bytes available: 22
    BlockSize: 20
    SIZE: 22
    SIZE: 22
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03c\x00\x00\x01P'
    b'\x00\x14\x00\x00\x00@\x00\x02f \x047:\xd0\x00\x00\x03\xb5\x00\x00\x00\xfc'

    Bytes available: 22
    BlockSize: 20
    Bytes available: 4118
    BlockSize: 20
    Bytes available: 4096
    BlockSize: 20
    Bytes available: 4074
    BlockSize: 20
    Bytes available: 4052
    BlockSize: 20
    Bytes available: 4030
    BlockSize: 2828
    GameSeverThread: action [2827] unhandled!
    Bytes available: 4020
    BlockSize: 2827
    GameSeverThread: action [2828] unhandled!
    Bytes available: 4010
    BlockSize: 2828
    GameSeverThread: action [2827] unhandled!
    Bytes available: 4000
    BlockSize: 2827
    GameSeverThread: action [2828] unhandled!
    Bytes available: 3990
    BlockSize: 2828
    GameSeverThread: action [2827] unhandled!
    Bytes available: 3980
    BlockSize: 2827
    ...

    Here are the code of the client thread that sends the byte arrays:

    Qt Code:
    1. class HandleClientRequestThread(QThread):
    2.  
    3. def __init__(self, socket, request, rqLock, parent):
    4. super(HandleClientRequestThread, self).__init__(parent)
    5. self.socket = socket
    6. self.rqLock = rqLock
    7. self.request = request
    8. self.__toSend = []
    9.  
    10. def run(self):
    11.  
    12. while True:
    13.  
    14. self.rqLock.lock()
    15.  
    16. length = len(self.request)
    17.  
    18. while length > 0:
    19. r = self.request.pop(0)
    20. print(r)
    21. if self.socket.state() == QAbstractSocket.ConnectedState:
    22. self.socket.write(r)
    23. else:
    24. print("socket is not connected")
    25.  
    26. length = len(self.request)
    27.  
    28. self.rqLock.unlock()
    29. self.msleep(10)
    To copy to clipboard, switch view to plain text mode 

    The client thread read the list "request" where packets are stored into by the method issueRequest() below. This later method is called
    through a slot that is connected to a signal sent by a QGraphicsItem when this one has moved.


    Qt Code:
    1. class GameClient(QWidget):
    2.  
    3. def __init__(self, gameWindow):
    4. super(GameClient, self).__init__(None)
    5.  
    6. self.socket = QTcpSocket()
    7. self.rqLock = QMutex()
    8.  
    9. self.myPlayerId = 0
    10. self.resetWork()
    11.  
    12. self.connect(self.socket, SIGNAL("connected()"), self.startNetworkThread)
    13. self.connect(self.socket, SIGNAL("readyRead()"), self.readFirstResponse)
    14. self.connect(self.socket, SIGNAL("disconnected()"), self.serverHasStopped)
    15. self.connect(self.socket, SIGNAL("error(QAbstractSocket::SocketError)"),
    16. self.serverHasError)
    17.  
    18.  
    19. def startNetworkThread(self):
    20.  
    21. self.thread = HandleClientRequestThread(self.socket, self.request,
    22. self.rqLock, self)
    23. self.connect(self.thread, SIGNAL("finished()"),
    24. self.thread, SLOT("deleteLater()"))
    25. self.thread.start()
    26.  
    27.  
    28. def issueRequest(self, action, params):
    29.  
    30. req = QByteArray()
    31.  
    32. stream = QDataStream(req, QIODevice.WriteOnly)
    33. stream.setVersion(QDataStream.Qt_4_6)
    34. stream.writeUInt16(0)
    35. stream.writeUInt16(action)
    36. stream.writeUInt16(self.gameId)
    37. stream.writeUInt32(self.myPlayerId)
    38.  
    39. for arg in params:
    40. arg.writeOnStream(stream)
    41.  
    42. stream.device().seek(0)
    43.  
    44. print("SIZE: %d" % req.size())
    45.  
    46. stream.writeUInt16(req.size() - SIZEOF_UINT16)
    47.  
    48. self.rqLock.lock()
    49. self.request.append(req)
    50. self.rqLock.unlock()
    To copy to clipboard, switch view to plain text mode 


    I hope you will have some new hints to resolve my problem.

    Best regards.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    In general something causes your socket to go out of "connected" state which causes your thread to exit which causes it to be deleted (as tbscope noticed) which causes you to access a stale object upon receiving data from the socket. First thing you should do is to get rid of the state check. It'd be best if you turned your synchronous approach into asynchronous that uses signals and slots so that you can get rid of the thread and possibly solve all your problems in one go.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    I've already modify the client to send packets without the intermediary thread, and it does not resolve the problem :/ (Moreover if my client is disconnected it will print this fact).
    So there was just threads at the server side, and checking the state here is precisely good in order to avoid accessing the socket if it is disconnected.

    (BTW, my client is more asynchronous with a threading approach than without one)

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    I don't think modifying the client will solve the server's problems...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Nov 2010
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    I suppose that it is a problem at the server side, but maybe packets are "incorrectly" sent at the client side.
    I will code the server in a mono-threaded approach to see if it resolves problems, but I will like to know what is wrong with my current code.

    Thanks for your help.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

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

    In short you are probably assuming too many things. Client and server are autonomous systems and they have to be treated like that.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

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