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

Author Topic: TCP dropping packets?  (Read 10476 times)

0 Members and 1 Guest are viewing this topic.

Z_guy

  • Newbie
  • *
  • Posts: 8
    • View Profile
TCP dropping packets?
« on: May 07, 2011, 12:19:57 am »
Hi!

I'm using non-blocking TCP sockets, which I call Receive() on every frame. They seem to be dropping packets quite often, even when I'm running both the server and the client on the same machine.

I've checked with Wireshark and the server computer is receiving the packets but the application doesn't receive them for some reason.

Anyone got any idea?

GatorQue

  • Newbie
  • *
  • Posts: 36
    • View Profile
Dropping TCP packets
« Reply #1 on: May 07, 2011, 09:30:21 pm »
Not knowing a lot about your code I can only offer the following ideas:

- The connection was accidentally closed (unlikely if your only missing a few packets, likely if your missing a series of packets in a row)
- The packets were received in the wrong order (TCP tries to make sure that all packets are received in the right order)
- The packets being sent were larger than 1472 bytes in size and therefore were split into multiple smaller packets, but some of these smaller packets were lost.  This might explain the loss, but TCP is suppose to resend the packets if some were lost in transmission.
- The packets were dropped because your TCP buffer is FULL.  This can happen if your sending the packets faster than the other end can process them.  The operating system helps by buffering the packets up to a certain point, but after that there is no buffers available and the packets might get dropped.  Try to see if you can compute (with wireshark) how fast the packets are being sent and see if you can add some delay to your sender and see if your packets stop getting dropped.
- Some other issue that I don't know.

Ryan Lindeman

Z_guy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Dropping TCP packets
« Reply #2 on: May 08, 2011, 12:54:36 am »
Quote from: "GatorQue"
Not knowing a lot about your code I can only offer the following ideas:

- The connection was accidentally closed (unlikely if your only missing a few packets, likely if your missing a series of packets in a row)
- The packets were received in the wrong order (TCP tries to make sure that all packets are received in the right order)
- The packets being sent were larger than 1472 bytes in size and therefore were split into multiple smaller packets, but some of these smaller packets were lost.  This might explain the loss, but TCP is suppose to resend the packets if some were lost in transmission.
- The packets were dropped because your TCP buffer is FULL.  This can happen if your sending the packets faster than the other end can process them.  The operating system helps by buffering the packets up to a certain point, but after that there is no buffers available and the packets might get dropped.  Try to see if you can compute (with wireshark) how fast the packets are being sent and see if you can add some delay to your sender and see if your packets stop getting dropped.
- Some other issue that I don't know.

Ryan Lindeman

Thank you for your answer.

I am sending a packet every time I press or release a button on the keyboard. That's the only traffic going between the client and the server. But some of the packets still get lost even over localhost.

GatorQue

  • Newbie
  • *
  • Posts: 36
    • View Profile
Dropping TCP packets
« Reply #3 on: May 08, 2011, 01:00:47 am »
Would it be possible to post the relevant code where these packets are created and where they are processed?

Z_guy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Dropping TCP packets
« Reply #4 on: May 08, 2011, 02:30:16 am »
Quote from: "GatorQue"
Would it be possible to post the relevant code where these packets are created and where they are processed?

Sure!

This is where the packet is created. This is done every frame.
Code: [Select]

if (timer.GetElapsedTime() >= 0.01f))
{
timer.Reset();
Input input(GetInput());
if (input != lastInput)
{
sf::Packet packet;
packet << PacketTypeValue(PT_INPUT);
packet << input;

socket.Send(packet);

lastInput = input;
}
}


This method is also called every frame
Code: [Select]

void NetworkManager::Update()
{
sf::Packet packet;

for (ClientList::iterator it = clients.begin(); it != clients.end(); ++it)
{
sf::SocketTCP sock = (*it).socket;
sf::Socket::Status status = sock.Receive(packet);
if (status == sf::Socket::Disconnected)
{
Disconnect(*it);
}
else if (status == sf::Socket::Done)
{
PacketTypeValue pt;
packet >> pt;

if (pt == PT_INPUT)
{
packet >> (*it).input;
}
}
}
}

GatorQue

  • Newbie
  • *
  • Posts: 36
    • View Profile
Dropping TCP packets
« Reply #5 on: May 08, 2011, 05:02:50 am »
I think I might know the problem.  According to some internet notes, the recv() method will return -1 if you try to read a packet on a NON-BLOCKING socket when there is nothing to be read.  This will in turn cause the Socket class to return an Error status to the parent method call which will then abort the reading of the packet right then and there.

So what is the answer you might be asking?  It appears that the internet suggests using the "select" call to wait for the socket to be ready before performing the Read operation.  I would suggest you try looking at the "Select" tutorial and use the Socket.Wait(timeout) method before performing the Socket.Receive method to get the packet, otherwise your NON-BLOCKING connection might get half-way through reading the packet and run out of bytes and return without giving you the full packet.  This might be a bug in the way the SFML TCP Socket class handles NON-BLOCKING Receives, we may want to investigate a little more into the Receive method and determine what if anything can be done to make the Receive(Packet) method more robust when the socket is NON-BLOCKING.

Please let me know if you have any questions and good luck!

Z_guy

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Dropping TCP packets
« Reply #6 on: May 08, 2011, 06:22:29 am »
Quote from: "GatorQue"
I think I might know the problem.  According to some internet notes, the recv() method will return -1 if you try to read a packet on a NON-BLOCKING socket when there is nothing to be read.  This will in turn cause the Socket class to return an Error status to the parent method call which will then abort the reading of the packet right then and there.

So what is the answer you might be asking?  It appears that the internet suggests using the "select" call to wait for the socket to be ready before performing the Read operation.  I would suggest you try looking at the "Select" tutorial and use the Socket.Wait(timeout) method before performing the Socket.Receive method to get the packet, otherwise your NON-BLOCKING connection might get half-way through reading the packet and run out of bytes and return without giving you the full packet.  This might be a bug in the way the SFML TCP Socket class handles NON-BLOCKING Receives, we may want to investigate a little more into the Receive method and determine what if anything can be done to make the Receive(Packet) method more robust when the socket is NON-BLOCKING.

Please let me know if you have any questions and good luck!


Thanks a lot!
I finally solved it, it actually turned out to be a quite silly mistake.
Code: [Select]

sf::SocketTCP sock = (*it).socket;

sock should be a reference, so this solved the problem
Code: [Select]

sf::SocketTCP &sock = (*it).socket;

I was making copies of the socket every frame.

Thank you for your help!

GatorQue

  • Newbie
  • *
  • Posts: 36
    • View Profile
Dropping TCP packets
« Reply #7 on: May 08, 2011, 07:10:54 am »
Great catch, glad you were able to find the problem.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
TCP dropping packets?
« Reply #8 on: May 08, 2011, 10:55:33 am »
Sorry GatorQue but there are many things to correct in what you said ;)

Quote
- The packets were received in the wrong order (TCP tries to make sure that all packets are received in the right order)

TCP doesn't only try, it ensures that packets are received in the right order.

Quote
- The packets being sent were larger than 1472 bytes in size and therefore were split into multiple smaller packets, but some of these smaller packets were lost. This might explain the loss, but TCP is suppose to resend the packets if some were lost in transmission.

TCP is not only supposed to, it ensures that no packet is lost.

Quote
I think I might know the problem. According to some internet notes, the recv() method will return -1 if you try to read a packet on a NON-BLOCKING socket when there is nothing to be read. This will in turn cause the Socket class to return an Error status to the parent method call which will then abort the reading of the packet right then and there.

This is not true, non-blocking sockets are properly handled in SFML and there is a dedicated return code for the "not ready" status. Implementations also ensures that partially received packets are properly cached until they are full.

Quote
This might be a bug in the way the SFML TCP Socket class handles NON-BLOCKING Receives, we may want to investigate a little more into the Receive method and determine what if anything can be done to make the Receive(Packet) method more robust when the socket is NON-BLOCKING.

You should at least have had a look at it before saying SFML is buggy... ;)
Laurent Gomila - SFML developer

GatorQue

  • Newbie
  • *
  • Posts: 36
    • View Profile
Dropping TCP packets
« Reply #9 on: May 08, 2011, 03:54:04 pm »
My apologies, I have dealt with buggy TCP code at work and made an assumption that was wrong without trying it out, please forgive me.