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

Author Topic: Advice for TCP sending?  (Read 5755 times)

0 Members and 2 Guests are viewing this topic.

enigma22134

  • Newbie
  • *
  • Posts: 13
    • View Profile
Advice for TCP sending?
« on: June 08, 2016, 05:53:55 am »
Hey guys, I'm attempting to write a basic TCP networking class. Currently, I have a server that allows 8 clients to connect and packets can be exchanged between the server and its clients.

 I have no experience with networking, but my approach is:
1) loop through all connected clients and request data (socket.receive())
2) process the data and determine what data should be sent out
3) send (socket.send()) an identical packet to all clients for updating the clients data.
4) repeat

I've implemented a method using a socket selector that times out the TcpSocket's receive method; my idea is that to design my packets so that if one is late, the packet following it will be sufficient to bring the program up to speed.

Anyways, I'm wondering what to do about sending. I cannot create a similar timeout method using socket selectors for the TcpSocket's send. I looked at the API and I am a little bit unsure how send behaves when the recipient doesn't respond.
http://www.sfml-dev.org/documentation/2.3.2/classsf_1_1TcpSocket.php#a0f8276e2b1c75aac4a7b0a707b250f44
Does it wait (block) until the recipient finally signals that that packet was received? What I would like to do is attempt to send a packet for X amount of time, if the send wasn't successful in that time, then the program would continue onward. Unfortunately, I'm not seeing a way to do this with TCP.

I do not want to set the send to non-blocking, because I am worried that a lag in the network would allow data to backup on one end of the network due to multiple attempts to send before the previous sends are complete.

It looks like I may have to switch to UDP, but I was hoping someone may have some ideas/knowledge.

Either way, thanks a bunch for reading. :)

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Advice for TCP sending?
« Reply #1 on: June 09, 2016, 03:45:40 am »
What you want is called a "ping" or "heartbeat" and its what a lot of (If not all) games implement as a rough detection for when a socket is timing out. You send a packet every n seconds and if you havent received one in n2 seconds, you are timing out. Personally I would recommend TCP for this considering that TCP guarantees the packet will be received where as UDP is connectionless and its kind of important that a ping packet get received.

As for wait, it takes a time out (In sf::Time) where it will block for that amount of time before unblocking. I would advise that you use that with about a 200ms wait time which is more than enough time per frame to allocate for networking.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Advice for TCP sending?
« Reply #2 on: June 09, 2016, 07:38:29 am »
I don't think he is looking for a ping/heartbeat, instead the problem or rather concern is the fact that the send function will block as long as data is sent and the fact that there's no timeout option or "polling" as with a socket selector.

The solutions are as you feared, non-blocking sockets or UDP sockets. Depending on the data you're sending, I'd suggest to use UDP socket, which work great with "fire and forget" method.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

enigma22134

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: Advice for TCP sending?
« Reply #3 on: June 11, 2016, 01:12:13 am »
eXpl0it3r's understanding of my issue is correct. What I'm thinking about doing is moving most of my game-related data to being transferred over UDP. I will only use TCP for pinging.

Here's how I'm thinking of doing it,

I will have the server check (wait) for a ping packet every X seconds from a TCP socket; thus not needing to do a blocking send. If it doesn't arrive, it will tally a missed ping. At some threshold (say, maybe 10 missed pings) it will prompt to disconnect the client and make that socket available for another player to join.

So, as to my problem with blocking. I think I will continue to use a timeout(polling) on the server end; however, I will make the socket non-blocking on the client's end. That way the client doesn't freeze when it attempts to send the TCP ping packet to a dead server. I guess I will have to learn how to handle partial packets.


I wonder, is it a bad idea to expect a UDP packet from the clients every server cycle? With some packets lost occasionally, of course. There would probably be 30-60 cycles per second. I'm thinking of sending nearly blank packets if there is no useful data to send, but I have no idea if this will interfere with other networking on the computer.