PDA

View Full Version : Reading problem at some (kind of random) point with QTcpSocket



tuxiko
29th November 2010, 17:48
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:



class GameServer(QTcpServer):

def __init__(self, parent=None):
self.games = []
self.gameId = 0

super(GameServer, self).__init__(parent)

self.players = {}
self.idList = [0]

self.startLck = QMutex()

self.startLck.lock()

def incomingConnection(self, socketId):

if len(self.idList) > 2:
return

i = 0
playerId = random.randint(10,300000)

while i < len(self.idList):
if self.idList[i] == playerId:
playerId = random.randint(10,300000)
else:
i += 1

self.idList[i-1] = playerId
self.idList.append(0)

socket = QTcpSocket()
if not socket.setSocketDescriptor(socketId):
self.emit(SIGNAL("error(int)"), socket.error())
return

self.players[playerId] = socket

reply = QByteArray()
stream = QDataStream(reply, QIODevice.WriteOnly)
stream.setVersion(QDataStream.Qt_4_6)
stream.writeUInt16(0)

stream.writeUInt32(playerId)

stream.device().seek(0)
stream.writeUInt16(reply.size() - SIZEOF_UINT16)
socket.write(reply)

socket.waitForBytesWritten()

thread = GameServerThread(self, self.players, playerId, self.startLck)
self.connect(thread, SIGNAL("finished()"),
thread, SLOT("deleteLater()"))
self.connect(thread, SIGNAL("debugPymagic"), self.DEBUG_GameServer)

thread.start()

if len(self.idList) == 3:
self.startLck.unlock()


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



class GameServerThread(QThread):

def __init__(self, parent, players, playerId, startLck):
super(GameServerThread, self).__init__(parent)

self.startLck = startLck

self.players = players
self.playerId = playerId

self.nextBlockSize = 0

def run(self):

self.startLck.lock()
self.startLck.unlock()

socketToNotify = []
for key, socket in self.players.items():
if key != self.playerId:
socketToNotify.append(socket)
else:
self.socket = socket

while self.socket.state() == QAbstractSocket.ConnectedState:

stream = QDataStream(self.socket)
stream.setVersion(QDataStream.Qt_4_6)

self.nextBlockSize = 0

if self.socket.bytesAvailable() < SIZEOF_UINT16:
while True:
self.socket.waitForReadyRead(-1)
if self.socket.bytesAvailable() >= SIZEOF_UINT16:
break

self.nextBlockSize = stream.readUInt16()

if self.socket.bytesAvailable() < self.nextBlockSize:
while True:
self.socket.waitForReadyRead(-1)
if self.socket.bytesAvailable() >= self.nextBlockSize:
break

pos = QPoint()

action = stream.readUInt16()
gameId = stream.readUInt16()
playerId = stream.readUInt32()

params = []

if action in (Action.SetCardPos, Action.SetCardZone):

cardId = stream.readUInt32()
params.append(Parameter(cardId, Parameter.UInt32))

if action == Action.SetCardPos:
stream >> pos
params.append(Parameter(pos, Parameter.Position))

elif action == Action.SetCardZone:
cardName = stream.readQString()
zone = stream.readUInt16()

params.append(Parameter(cardName, Parameter.String))
params.append(Parameter(zone, Parameter.UInt16))

if cardName == "token":
color = stream.readQString()
power = stream.readUInt16()
toughness = stream.readUInt16()

params.append(Parameter(color, Parameter.String))
params.append(Parameter(power, Parameter.UInt16))
params.append(Parameter(toughness, Parameter.UInt16))

else:
print("GameSeverThread: Unknow action!")
continue

else:
print("GameSeverThread: action [%d] unhandled!" % action)
continue


for sck in socketToNotify:
self.sendRequest(sck, action, gameId, playerId, params)


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.

tuxiko
29th November 2010, 21:18
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]

wysota
29th November 2010, 21:31
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:

while self.socket.bytesAvailable() < SIZEOF_UINT16:
self.socket.waitForReadyRead(-1)

tuxiko
29th November 2010, 23:31
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.




...
while self.socket.state() == QAbstractSocket.ConnectedState:

self.nextBlockSize = 0

while self.socket.bytesAvailable() < SIZEOF_UINT16:
self.socket.waitForReadyRead(-1)

print("Bytes available: %d" % self.socket.bytesAvailable())
self.nextBlockSize = stream.readUInt16()

if self.nextBlockSize == 0:
print("GameServer: Problem with QTcpSocket?!\n"
"QDataStream status(): %d" % stream.status())
return

while self.socket.bytesAvailable() < self.nextBlockSize:
self.socket.waitForReadyRead(-1)

print("BlockSize: %d" % self.nextBlockSize)
...


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:



while self.socket.bytesAvailable() < SIZEOF_UINT16:


What does it means?

Thanks for all your patience.

wysota
29th November 2010, 23:59
I think something might have deleted your socket.

tbscope
30th November 2010, 05:54
One big problem I see is this:

self.connect(thread, SIGNAL("finished()"), thread, SLOT("deleteLater()"))

What happens if you delete or comment that line?

tuxiko
30th November 2010, 21:01
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:



class HandleClientRequestThread(QThread):

def __init__(self, socket, request, rqLock, parent):
super(HandleClientRequestThread, self).__init__(parent)
self.socket = socket
self.rqLock = rqLock
self.request = request
self.__toSend = []

def run(self):

while True:

self.rqLock.lock()

length = len(self.request)

while length > 0:
r = self.request.pop(0)
print(r)
if self.socket.state() == QAbstractSocket.ConnectedState:
self.socket.write(r)
else:
print("socket is not connected")

length = len(self.request)

self.rqLock.unlock()
self.msleep(10)


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.




class GameClient(QWidget):

def __init__(self, gameWindow):
super(GameClient, self).__init__(None)

self.socket = QTcpSocket()
self.rqLock = QMutex()

self.myPlayerId = 0
self.resetWork()

self.connect(self.socket, SIGNAL("connected()"), self.startNetworkThread)
self.connect(self.socket, SIGNAL("readyRead()"), self.readFirstResponse)
self.connect(self.socket, SIGNAL("disconnected()"), self.serverHasStopped)
self.connect(self.socket, SIGNAL("error(QAbstractSocket::SocketError)"),
self.serverHasError)


def startNetworkThread(self):

self.thread = HandleClientRequestThread(self.socket, self.request,
self.rqLock, self)
self.connect(self.thread, SIGNAL("finished()"),
self.thread, SLOT("deleteLater()"))
self.thread.start()


def issueRequest(self, action, params):

req = QByteArray()

stream = QDataStream(req, QIODevice.WriteOnly)
stream.setVersion(QDataStream.Qt_4_6)
stream.writeUInt16(0)
stream.writeUInt16(action)
stream.writeUInt16(self.gameId)
stream.writeUInt32(self.myPlayerId)

for arg in params:
arg.writeOnStream(stream)

stream.device().seek(0)

print("SIZE: %d" % req.size())

stream.writeUInt16(req.size() - SIZEOF_UINT16)

self.rqLock.lock()
self.request.append(req)
self.rqLock.unlock()



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

Best regards.

wysota
30th November 2010, 23:08
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.

tuxiko
1st December 2010, 07:28
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)

wysota
1st December 2010, 08:47
I don't think modifying the client will solve the server's problems...

tuxiko
1st December 2010, 09:14
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.

wysota
1st December 2010, 11:28
In short you are probably assuming too many things. Client and server are autonomous systems and they have to be treated like that.