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

Author Topic: After tcplistener.close() I have to restart the server?  (Read 13348 times)

0 Members and 1 Guest are viewing this topic.

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
After tcplistener.close() I have to restart the server?
« on: March 30, 2013, 11:50:10 am »
Hy,
my application uses one port for communication with the client. I use tcp so i create a sf::tcpListener, listen on that port and handle incomming connections, all works fine. When I close the app I call the tcpListener.close() function.
But when i open another instance (after closing the previous one) i get an error in the command line (Failed to bind Port XXXX). After a reboot of the server all works fine again until i close and reopen the application.

Is this a known bug? or do I have to call anything else when i close my server?


AlexAUT

Varonth

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: After tcplistener.close() I have to restart the server?
« Reply #1 on: March 30, 2013, 03:34:32 pm »
So do I get this right?
When the client application gets closed, you are calling ::close on the TcpListener of your server application?

If that's the case, yeah your server cannot accept new connections.
The TcpListener willl create a new TcpSocket using the Socket object given as argument. That Socket will then handle all the connections received by that client. The TcpListener can then continue to listen on it's port, while the client socket is now bound to another free port. That allows you to accept multiple connections with just one listener. The client therefore just has to know the port of the TcpListener, and the server will then establish a TcpConnection on a free port. In case of a game for example, you just have to tell other players the port the TcpListener is listening on, and you also just have to forward connection request of that port in router and firewall settings etc. The port forwarding isn't needed for established connections, just for accepting incoming connection.

Now if the client closes his connection your server should close and handle the disconnect from the client socket. The TcpListener should be unaffected and should just be closed once it isn't needed anymore, so once your server should no longer accept new connections.

TL;DR (hopefully you did)
You should not close your listener port, unless you don't want to accept new connections. On client disconnect you just close the client socket given as argument to sf::TcpListener::accept

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: After tcplistener.close() I have to restart the server?
« Reply #2 on: March 30, 2013, 03:59:37 pm »
Thanks for the explanation, but my i think you missunderstood my problem  ::)

So do I get this right?
When the client application gets closed, you are calling ::close on the TcpListener of your server application?

No when the server application gets closed.


Ther server works fine, multiple clients are no problem and I dont close the Listener when a client disconnects, I disconnect the client socket.

My problem occurs when i shutdown the server to install an update or something like that. I do that this way:

1)I send a packet to my server wich contains the message to shutdown
2)The server closes all client sockets
3)The server closes the listener
4)The app reaches the return of the "main"

Then i replace the executable with the new version. And now, when I start the new version, I get the Error: "Cant bind Port xxxx".

So it looks like the old instance still blocks the Port but the old instance isnt running anymore.
The strange thing is that this "bug" online happens under Linux on my PC/Windows I can open/close the server without problems.


AlexAUT

Varonth

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: After tcplistener.close() I have to restart the server?
« Reply #3 on: March 30, 2013, 04:13:20 pm »
Ah ok, that makes a bit more sense now.

Ever took a look at netstat after closing your server application?

Try
sudo netstat -npl

It should show you all listening socket including the process they belong to.

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: After tcplistener.close() I have to restart the server?
« Reply #4 on: March 30, 2013, 04:25:09 pm »
Thanks for your quick answer

Result of netstat -npl :

It only shows the ssh connection. So the 60510 should be free... But when i start my server it tells me "Cant bind the Port 60510"


As I said on windows all works fine...


AlexAUT

Varonth

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: After tcplistener.close() I have to restart the server?
« Reply #5 on: March 30, 2013, 04:36:50 pm »
It just shows one listening socket, which is probably listening on port 22 (that's the standard for SSH).

If so, that is kinda weird considering how many processes use sockets for inter-process communications on localhost.

You could always try different arguments aswell for netstat.
« Last Edit: March 30, 2013, 04:40:27 pm by Varonth »

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: After tcplistener.close() I have to restart the server?
« Reply #6 on: March 30, 2013, 04:44:26 pm »

Exact result:


When my server application is running:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      104/sshd
tcp        0      0 0.0.0.0:60600           0.0.0.0:*               LISTEN      446/kroniax_server
tcp6       0      0 :::22                   :::*                    LISTEN      104/sshd
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     1246989900 1/init              @/com/ubuntu/upstart
unix  2      [ ACC ]     SEQPACKET  LISTENING     1246990224 117/udevd           /run/udev/control

 


After the shutdown of the server application:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      104/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      104/sshd
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     1246989900 1/init              @/com/ubuntu/upstart
unix  2      [ ACC ]     SEQPACKET  LISTENING     1246990224 117/udevd           /run/udev/control
 

Btw its a vServer, so maybe i cant see everything.

I think I have to deal with it and restart the server everytime i update the server software...


AlexAUT


Varonth

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: After tcplistener.close() I have to restart the server?
« Reply #7 on: March 30, 2013, 05:08:07 pm »
Oh well, I think I might know what is going on.

Could you try netstat again, after shutting down, but instead of getting all listening ports you should look for TcpSockets in the state "TIME_WAIT".

If it is still there, you might just have to wait a few minutes until you can restart your server application.

Just remove the -l argument from netstat, or add -a to it.

Normally netstat will not display listening ports, thats what the -l does. -a shows all Sockets.

Edit:
A nice article about TIME_WAIT and TcpSockets http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: After tcplistener.close() I have to restart the server?
« Reply #8 on: March 30, 2013, 05:22:01 pm »
Yeah that was the "problem". The article explains this topic very well.

Thanks for your help  :)


AlexAUT

 

anything