Is TCP truly "guaranteed delivery"?

Ok so i know TCP is supposed to be guaranteed delivery and delivered in the correct order but I have come across a situation where it would seem that a TCP “message” was lost all together. Is this possible or is this a flaw in my code?

In detail:

I have a turn based game and it worked perfectly well for 3 or 4 games but on the 5th game a strange thing occurred where me and the person I was playing got stuck on a screen that said “waiting for opponent to take their turn.” However, I don’t think the entire connection was blown since me and the other player could send “chat” messages back and forth (using the same port and socket). Therefore leading me to believe that the data for my turn was simply lost.

its very likely that it is a problem in your code. I have never had a problem like that with TCP.

its more likely that a connection will time-out then send wrong information.

that said, if you are using Threading make sure information is accessed in order.

I would suggest going over your code thoroughly

Tcp can timeout but not get lost without a trace.

I would check all try-catch in my code to see if an exception gets lost somewhere.

ok thats what I was thinking but just wanted to make sure. Just to clarify, there is no possible way that messages will get out of order either right? Meaning if there is a problem with a certain message the connection will timeout rather than send the next message?

if a problem with data or a “message” is found in the connection then TCP deals with it, and would likely send the required data again, so that it is recieved in order. Only a time-out would cause a time-out.

Granted TCP can run into other problems for example, in your code you could possibly be trying to recieve the wrong kind of data.
eg. when sending an int, and trying to recieve a UTF.

TCP issues are rarely illusive.

Just to clarify: you are talking about keeping a single connection open and sending multiple messages down it?

Yes I am.

However, I currently send everything as a string and parse it for whatever data is needed. I’m going to check my code must be my mistake. Thanks for the info guys.

In multiplayer games, log log log. Every time any message is received or sent it should be appended to a giant log file (or just the console if you want). That way you can look for “sent turn end packet” and “received turn end packet,” then trace when and where each of those things happen.

Eli can you be more specific? How does logging help me? And I’m assuming you mean on the server side program? Or server and client?

Tcp is only guaranteed at the lowest possible level where the OS receives the data. There is plenty of code between that and your application where bugs can occur. That said, the by far most likely place for data to get lost is in your own code.

Are both sides “waiting for the opponent”? That sounds more like a deadlock condition, each side waiting for the other to release a needed resource.

Sure, log everything at the lowest possible level. Then you know will know for sure what got sent and when.

I mean on both. And if possible you can combine the logs into one single log based on timestamp. You basically need to do this to figure out if you’ve got a deadlock like philfrei suggests or something else.

Try testing extensively on localhost so that you can figure this one out, it will be much easier to trace exactly what is happening then trying to figure stuff out remotely. That’s just my opinion, though, depending on your setup this may not be the case.

But if you do it locally you can use breakpoints, which are a big win.

Ok yea that makes sense, at least for testing on a local machine I can see why that would be useful.

Like philfei suggested it was where both opponents were waiting. However, it was not something that I could duplicate and still haven’t seen it happen since. Thus I was wondering if TCP could possibly just lose information that way (my original question).

Abstractly this is how my game functions:

p1 connects to server.
p2 connects to server.
when two players are connected the server pairs them and creates a game.

p1 takes his turn.
the turn is animated on p1’s applet.
the information from the turn is then sent to the server.
server does necessary checking for cheating etc. and send the turn to p2.
p2 then animates p1’s turn.
p2 then takes his turn.

cycle repeats.

the game froze after I took my turn. the turn was successfully animated on my applet. thus I would think that data was also sent.
this is where logging would have been helpful.

it just seemed strange to me that it was such a random occurrence. however the game has not been thoroughly tested thus maybe the occurrence isn’t so random.

i’m going to set up a log and that should get me moving in the right direction. if anyone thinks the abstraction part above doesn’t sound like I’m doing something correctly let me know.

Another common variation, if you’re using blocking I/O, is for a process to block because it’s output buffer
is full, while the receiver is also blocked either for the same reason or because it is waiting for a response
that it thinks ought to be in the pipeline somewhere. You should not depend on the buffering
capacity of the TCP stream. You should never wait synchronously for a response.

My games have a
(a) a reader thread that reads messages from the TCP stream and queues them for the game
thread to process.
(b) a game thread that processes messages from the reader thread (and also other sources of input
such as the mouse and keyboard). It queues outgoing messages for a writer thread to deliver, but
never waits for them to be sent.
© a writer thread that sends messages that were queued for it to send.

I do something similar for receiving but I never thought of doing that on the sending part. I have a thread that queues messages that are received and then processed by the update thread of the game cycle (ie. update, render, draw). Even if this isn’t my problem doing it for the sending part would be a good idea. Thanks for the info.

While TCP is “reliable” it should be noted that a connection can go dark without throwing exceptions per say. That is the connection become a black hole direct to /dev/null. I have noticed to get solid TCP reliability i need to have my own timeouts where i then treat this the same as a socket exception (connection closed by… etc).

Also since you are using strings you can use something like tcpdump to see your network traffic.

I have heard of this happening previously. However, I was under the impression that setting a timeout using .setSoTimeout() would allow this condition to be caught? I have set up a ping-pong type communication between the server and the client per a suggestion in a previous thread. I was under the impression that if a thread blocked on say in.readLine() for longer than the time set with .setSoTimeout() a socket exception would be thrown. Is this incorrect?

I think that is correct. I am currently using non blocking IO. I would test it at anyrate, network code should never assume.

This problem happens in TCP when say your ISP gives you a new IP number. Now all the packets from the old TCP connection are not coming to you anymore, and no error or control packets were sent by either side. Basically it looks like a black hole of /dev/null. No matter how you set up the hand shaking you still have what is called the 2 generals problem, and that means that control packets can get lost and the connection goes dark without errors. TCP does have a keep alive, but IIRC it is typically very long/slow.

[quote=“delt0r,post:18,topic:36392”]
you can configure how long the keep-alive is.

make sure you flush your socket at the end of each message. if you message is too small the nagels algorithm will cause it to stay in the buffer indefinably if theres never any more data your trying to send.

even if the socket does time out at some point, you will not get an exception until you actually call anything on the socket. TCP once it hits the wire is do or die. if it doesn’t die, it did which is what guarantied with respect to TCP means.(also in a large sense, but explaining that is entirely fuzzy. it related to how real-time!=fast)

I have the nagels algo turned off for all my game tcp connections. I ensure that i am not doing anything silly like sending a single byte at a time.