I wrote this small server application in pure C that listens to incoming connections in a given port, very simple stuff.
It goes with the usual socket initialization procedure, create the socket()
then bind()
to the port, says its a listen()
, and ifinitely loops through a select()
waiting for incoming connections to accept()
.
All goes just fine and works like a charm, except that if I leave the thing running for a couple months, the listening port closes while the application server keeps running unaware of it, since I wrote it to trust the listening socket will not close if not told to.
So the question is: Why the hell is the port being closed without my application's concern and what can I do to prevent it from happening?
Is that expected behaviour? Should I check for some kind of exceptions or make "health check" on the listening socket to reopen it if necessary?
Code: https://gist.github.com/Havenard/e930be035a3bee75c018 (yes I realize I'm using 0
as cue for errors and it's bad pratice and stuff, but it is not relevant to the question as I explained in the comments, when I set the socket file descriptor to 0
it is to stop the loop and shut down the application).
A port number is a 16-bit unsigned integer, thus ranging from 0 to 65535.
The best way to resolve the port issue is to find an alternative unused port and map it to the application. This is more to do with the design of the application. As an example if port 80 is already in use by a web application then one can choose 8080 for another web application.
Listening port is a network port on which an application or process listens on, acting as a communication endpoint. Each listening port can be open or closed (filtered) using a firewall. In general terms, an open port is a network port that accepts incoming packets from remote locations.
I would start by cleaning it up:
if (n_case > 0) memcpy(nick, node->nick, (n_case > 32 ? 32 : n_case));
; sizeof is your friend.That's only a few hours of editing.
My guess is that, after cleanup/refactoring your "bug" will come to the surface magically.
Footnote: No,I won't do your work for you. Not for 100 points, not for 1000. Please clean up your own mess.
This answer is mostly a code review of places where you call close()
.
Line 330: You close the socket but don't continue right away like in other places in your code. This could lead to weird behavior.
Line 928: In most places, you set the client or server socket to 0
after a call to close()
. You don't after this call.
Line 1193: Same comment as line 928.
Line 1195: Same comment as line 928.
Line 1218: Same comment as line 928.
Line 1234: Same comment as line 928.
Line 1236: Same comment as line 928.
When I compiled the code with full warnings, I saw a number of places where the compiler noted functions declared to return a value, but no value is being returned.
x.c:582: warning: no return statement in function returning non-void
x.c:591: warning: no return statement in function returning non-void
x.c:598: warning: no return statement in function returning non-void
x.c:609: warning: no return statement in function returning non-void
x.c:620: warning: no return statement in function returning non-void
x.c:728: warning: no return statement in function returning non-void
x.c:779: warning: no return statement in function returning non-void
There are many other problems, as noted in other posts.
As far as debugging this issue, If I suspected the binding socket was being closed early, I would intercept the close()
call with my own version that asserts that the descriptor being closed should not match the binding socket.
However, as wildplasser noted, select()
would return an error about the invalid descriptor if it was closed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With