Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: TCP Connection  (Read 9301 times)

0 Members and 1 Guest are viewing this topic.

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
TCP Connection
« on: August 01, 2016, 01:15:57 pm »
Hi,

Let's assume that two users are connected through a TCP connection, with TCP sockets. During a very short amount of time (like 500 ms), the Internet connection between these two users is cut, for whatever reason. Unfortunately, during that short period of time, each user sent a (different) message to the other, using the TCP connection (sockets) that they set up earlier. When the Internet connection is up again, how will these two messages be handled ? Which one will be processed first, causing one user to get confirmation that their message went through first, before receiving the other user's message ?

Not sure if I'm clear enough, but thanks in advance for your input.

nicox11

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: TCP Connection
« Reply #1 on: August 01, 2016, 02:56:45 pm »
Quote
Which one will be processed first, causing one user to get confirmation that their message went through first, before receiving the other user's message ?

You can't know which one will arrive first, but TCP provides mecanisms to assure that packets will arrive. Except if connexion is lost forever.

Quote
When the Internet connection is up again, how will these two messages be handled ?

After a certain amount of time (timeout) when a sender doesn't receive acquittement from the receiver, the sender simply resend the packet.
« Last Edit: August 01, 2016, 03:03:00 pm by nicox11 »

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #2 on: August 01, 2016, 06:15:48 pm »
Here's my predicament.

Two players are connected to each other. They send messages to each other. A message starts a QPropertyAnimation that lasts 250 ms, and for various reasons it is important that only one QPropertyAnimation is processed at a time. While a QPropertyAnimation is being processed, a player isn't able to send other messages, and should he receive one, it would be ignored anyway.

Let's go straight to the unlucky/problematic scenario. Due to misfortune or due to an Internet lag, while no QPropertyAnimation is being processed, both users send a message at the same time. How can I make sure that each player processes the same message and discards the other message? (For various reasons, the other message has to be discarded instead of simply delayed.)

How should I implement that? For now, I plan to give each user one sf::TcpSocket for sending, and one sf::TcpSocket (+ one sf::TcpListener) for receiving. Is this smart, or should I use only one sf::TcpSocket for both sending and receiving?

Thank you in advance for enlightening me.

nicox11

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
Re: TCP Connection
« Reply #3 on: August 02, 2016, 10:12:42 am »
Sorry but it's not clear. If every players send one message to the other player, each player will have one message to proceed. So no need to discard any ?

You can use one socket to send and recieve.

Anyway, if the problem is to only play one annimation at a time a simple boolean will be enough, but i'm sure i didn't understand your problem.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: TCP Connection
« Reply #4 on: August 02, 2016, 01:38:20 pm »
I suggest you first get a good grips on how TCP works on its own. It's pretty hard to write code with a protocol you don't fully understand.

When two users send messages to each other there's no guarantee that the messages will arrive at the same time, as such you don't just have to handle differences when there's "lag", but you always have to handle it.
If A sends to B and at the same time B sends something to A, you have two messages that are completely independent of each other.

And as has been said before if the sender doesn't receive an ACK within a certain time frame, it will do a retransmission multiple times and after x amount of time or retries will stop with a time out.

Some further questions are, why is your QPropertyAnimation (whatever that is) blocking? Why can there be only one animation? And why can each user initiate an animation, yet only one can be played at the same time?
Maybe it would be best if you actually told as what you're trying to achieve. Maybe there are better solutions that the one you're forcefully trying to get to work.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #5 on: August 02, 2016, 06:26:41 pm »
I forgot to add that once a message went through, the exact same QPropertyAnimation is supposed to occur on the sender's end. So if Player 1 sends the message "Move Card_42 from pile A to pile B" and Player 2 sends the message "Move Card_42 from pile A to pile C" at the same time, one of the two players will have to forfeit their own message and follow the other one. The other message has to be discarded otherwise it would cause a segmentation fault  after the first message has been completely carried out. (Since Card_42 is no longer in pile A for neither player.)

So I need a way for players to know if their message has been acknowledged before or after they acknowledged their opponent's  message. If Player 1's message was acknowledged by Player 2 before Player 2 acknowledged Player 1's,  then it's obvious to both players that Player 1's message should be carried out, while Player 2's should be for ever disregarded.

Is this feasible with the SFML? If not, how would you solve this issue?
« Last Edit: August 02, 2016, 06:30:54 pm by Law »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: TCP Connection
« Reply #6 on: August 02, 2016, 06:42:39 pm »
Of course you can do that. You could for example simply timestamp the actions. So if player A executes the command before player B, player A's command will be used. This of course means if player B receives the command that player A was faster, he has to discard the moving that might already be happening and switch to whatever the command was from player A. This is tricky since you'll have to somehow store the previous position etc.

Other solutions are that you define one server, so like player A might host the server. That way every command gets first sent to the server and the server then decides which commands get actually executed and sends those to every client. That way every client will always receive the correct command.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: TCP Connection
« Reply #7 on: August 02, 2016, 06:51:45 pm »
Networking games is difficult. Especially over the internet. Period.

You may find it interesting to read this: http://fabiensanglard.net/doom3_documentation/The-DOOM-III-Network-Architecture.pdf

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #8 on: August 02, 2016, 10:16:41 pm »
Using a third-party server is definitely an option. But I would like people to be able to play on their own as well.

Timestamps aren't an option because it's impossible to make both players' clocks start at the same time.

The only solution that I could think of so far is: whenever a player gets a message, they immediately send a reply saying ok. And whenever a player sends a message, they wait for the ok reply before starting their own QPropertyAnimation. If the next message they get isn't ok, the QPropertyAnimation is aborted and nothing happens.

In the situation where two players send a message at the same time, the next message they get isn't ok, but the other player's message. So each player forfeits their QPropertyAnimation and they have to send a message again. It's highly unlikely that they'll manage to send a message at the same time twice in a row.

Thoughts?

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #9 on: September 18, 2016, 04:44:47 pm »
I'm sorry to bump this but I realize there's yet another basic thing I'm not sure I understood. If the socket the sender uses to send data has Status::Done, does this mean that the sender is sure that the recipient has got the message?

Conversely, if the socket the recipient uses to receive data has Status::Done, does this mean that the recipient is sure that the sender is sure that his message went through?

Additional comment:
I apologize if I'm being annoying, but I don't seem to be getting many replies. Is there anything wrong with my messages? Does anyone in the SFML coding team know how their Network library work at all? I'm sorry if I'm asking questions, but I'm lacking basic information. As a newbie I thought it'd be smart to get here and ask. I would also be interested to know how to make an sf::TcpSocket back on track if it has an sf::Status of Error or Disconnected, since I failed to find any relevant information in the tutorial about that :S

Thanks!
« Last Edit: September 18, 2016, 09:03:51 pm by Law »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: TCP Connection
« Reply #10 on: September 21, 2016, 02:35:56 pm »
Might be a good time to read up a bit on how TCP works, that way it will be a lot easier to understand what is going on.

The general flow is as follows:
  • Server sends X bytes of data to Client.
  • Client sends ACK for these X bytes to Server.
This way the server knows what the client has received and if not can start sending the missing packet etc. again.
Since TCP is a reliable transfer protocol you don't have to worry about any of that in your code, instead you can just depend on checking Done and know that data has been successfully exchanged.

I apologize if I'm being annoying, but I don't seem to be getting many replies. Is there anything wrong with my messages?
Nothing wrong with your question and you're certainly not annoying. It's just that some questions take a bit more effort to answer and then sometimes fall through. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #11 on: September 22, 2016, 10:52:31 am »
Thanks for replying eXpl0it3r! Really! I think I got the gist of it now.

What are the most common mistakes that newbies make with sf::TcpSockets though? I'm currently having a problem with my sf::TcpSockets. Once the connection is established (and it always is, I have no problem on that score), an sf::Packet of 418 data bytes is sent from the client's side in one piece (although the socket itself is non-blocking) and the result status is sf::Socket::Status::Done. On the server's side, sf::TcpSocket::receive(sf::Packet&) always returns sf::TcpSocket::NotReady no matter what. The problem remains exactly the same if I try to send something from the server, and try to receive that thing on the client's side.

I repeated this experiment over and over and nothing has ever changed. I always send the sf::Packet successfully, but the other side never even sees it. My sf::TcpSocket is non-blocking and sf::TcpSocket::receive(sf::Packet&) is called by a QTimer every 10 ms.

Do I need to show some code, or could you share some common mistakes that I might have made first?
« Last Edit: September 22, 2016, 10:54:07 am by Law »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Re: TCP Connection
« Reply #12 on: September 22, 2016, 12:16:42 pm »
I think the most common mistake when it comes to networking that people do, is that they don't don't familiarize themselves enough with the topic. One should really understand what TCP does in its basic form, how a client-server architecture looks like, what blocking and non-blocking actually does and figure out how these modes should be used.

The FAQ already answers some of the potential questions and I can only recommend to read through it.

From your brief description it sounds like your code isn't really optimal. Why do you use non blocking sockets? Why are you not using a selector?
But to really be able to give a feedback, we'd need to see the minimal code.

Optionally you could as a first step take a look at the VOIP SFML example and try to adapt that design for your code.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Law

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: TCP Connection
« Reply #13 on: September 22, 2016, 01:01:47 pm »
Well unless you have a better idea, my project is a card game, and I intend the player to be able to interact with the game scene at all times ^^ (The player interacts only with the other player, there's no other people involved.) I didn't know there was a FAQ, so I read it and it made me install Wireshark. I could check that a frame (or whatever it's called) was indeed sent from the client to the server, and inside that frame was what I had written. (I wrote an std::string in that packet, and I could find and read it on Wireshark.) Wireshark spotted and listed that frame both from the client's computer, and from the server's.

Unfortunately, my socket keeps returning NotReady on the server's end. I must be missing something, since as I said the connection was successfully established, and the packet was successfully sent and received, if not by the sf::TcpSocket, at least by the server's computer.

:S

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: TCP Connection
« Reply #14 on: September 22, 2016, 01:24:27 pm »
You should at least show us your code that accepts connections and that receives data (on server side).
Laurent Gomila - SFML developer