Game Development Community

TCPObject listen not working after disconnect

by Valador, Inc. · in Torque Game Engine · 05/11/2007 (11:50 am) · 3 replies

I'm using TCPObject's listen functionality to read some data from a non-Torque client. All I do is call listen(port) and then have overridden the onReceive to do what I want with the data it's getting. Everything works exactly as it should until the client disconnects.

When another client tries to connect I get the "Got bad connected receive event." error message. I've traced through the code to see how TCPObject works and I've found the problem in tcpObject.cc. The first line of the DemoGame::processConnectedAcceptEvent function calls the find(tag) function to attempt to look up the tag in an array of TCPObject pointers. When the very first client connects it finds this tag and the client is able to pass messages to the Torque server. On subsequent client connects it can't find this tag and spits out the bad connected receive message.

Here's the sequence I've been able to figure out as to how this tag array gets filled.
Listen function called - Tag 1 added to table.
Client connects in - Tag 2 added to table, Tag 1 deleted from table.
Client passes data - Uses Tag 2 to find the appropriate TCPObject pointer from the table.
Client disconnects.
New Client connects - Looks for Tag 1 (which has been deleted from the table) and can't find it. Gives error.

I've tried removing the function that deletes the tags from the table, but that doesn't work. I've tried calling listen again on the same port which does create a Tag 3 in the table, but when the new client connects it's still looking for Tag 1.

Since the table just holds TCPObject pointers which are just a linked list of TCPObjects, I'm guessing that the Tag 1 TCPObject is getting deallocated somewhere when the first client disconnects. So even if it's not removed from the table, it still doesn't exist. I have no idea where this would be happening though and why can't I just call listen again on the same port to create a new listener.

Has anyone been able to get this kind of thing working? I just need it so when the first client disconnects, a new client can then connect in. Seems simple enough.

#1
05/11/2007 (2:15 pm)
TCPObject::table isn't sufficient to track the connections, and your problem sounds closely related to another problem I had with TCPObject.

I documented it here:

http://www.garagegames.com/mg/forums/result.thread.php?qt=53995
#2
05/14/2007 (6:26 am)
Yeah, that seems to be the same problem? Did you solve it by using a different library to do this or were you able to fix the Torque code? I've been trying to make sure all the objects have been deleted and the tag table is cleared out. The hope is that I can get things back to the same state they're in when the mission is first loaded since it works then.
#3
05/15/2007 (10:49 am)
I was able to fix this problem.

What was happening was the mTag variable in TCPObject was the only variable storing both the connectionTag and the portTag. So the process would go like this:

Listen On Port - mTag = portTag
Client Connects - mTag = connectionTag
Client Disconnects
Client Reconnects - Looks for portTag in the mTag variable, but only finds connectionTag
Throws bad connected received error.

The solution was to add a new member variable to TCPObject called portTag which only stores the port tag. mTag continues to store the connection tag. Then when processConnectedAcceptEvent is called I call a findPort function instead of just the find function. The findPort function behaves exactly like the find function, but instead of looking at mTag looks at the new portTag member variable in TCPObject.

With this process I am able to listen once on a port and reconnect as many times as I need to.