[SOLVED] How could server detect closed client socket using TCP and c++?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
How could server detect closed client socket using TCP and c++?
Hi,
Reading some examples on net and copying some codes I was able to build a (frankstein) server that accept connection from one client and receive and send messages to it. The big problem that shows up is that I don't know when client disconnects from my server.
I've been looking for a solution, but no success. I'd read about SO_KEEPALIVE option (which could solve my problem), but I don't know how to use it (how to check the value of it).
I can't use ping because the server (machine) could be running, but not the client (software).
Anyone knows a good tutorial or how to (for beginners like me xD) of TcpIp sockets using c/c++ and how to detect when a client disconnect?
Q: TCP client application does not detect network failure
A: You're tripping over a basic reality of How TCP/IP (and hence the Entire Freakin Internet) Works. Go find Stevens' "UNIX Network Programming" (ISBN 0-13-490012-X.), and read it. Then read it again.
Repeat until the giant glowing lightbulb appears over your head and an angelic chorus of deceased network engineers descends from the heavens repeating the seven OSI layers in Gregorian chant. Then you'll know you've Gotten It.
Q: Why does it take so long to detect that the peer died?
A: ...
The approach taken by most application protocols currently in use on the Internet (e.g. FTP, SMTP etc.) is to implement read timeouts on the server end; the server simply gives up on the client if no requests are received in a given time period (often of the order of 15 minutes).
Protocols where the connection is maintained even if idle for long periods have two choices:
1. use SO_KEEPALIVE
2. use a higher-level keepalive mechanism (such as sending a null request to the server every so often).
I read the links (and a lot of other links), but no practical solution yet. My project is like a data logger, so I just need that my client connect, receive some data from me, disconnect, connect again, receive data... and repeat this procedure when the client need to get some information (that means any time of day).
I'll try to do some tests here... but I'm losing my hope of find a simple solution :/
It sounds like everything you're trying to do, sockets already does for you! Specifically:
1. You start your server.
He sets himself up, and starts listening for client requests.
2. You start your client. He wants to exchange information with the server.
3. The client "connects".
At that point, a NEW socket is created on the server, specifically for THAT connection.
Your server can do whatever he wants with that connection to service it - including start a new thread, or fork off a new process.
4. At some point, the server goes back and resumes listening for new connection requests. If he forked a new process, he can do it immediately (both the "server" process and the "service handler" process can run at the same time). Otherwise, you can't read any new connections until you're done servicing the current one (which is often perfectly acceptable).
5. Either way, at some point: the client is done, and he closes his socket. The server is done, and he closes his socket. The connection closes, and everybody's happy.
Thanks again for your help. The problem is that I don't know when the client finished his job, moreover, the server will send some status to the client like a 'hey client, someone pushed my button here!' (obviously, when the client is connected) in a kind of 'online communication'. Unfortunately, I can't use poll :/.
I solved this issue by using select function inside a thread.
Thanks again for your help. The problem is that I don't know when the client finished his job, moreover, the server will send some status to the client like a 'hey client, someone pushed my button here!' (obviously, when the client is connected) in a kind of 'online communication'. Unfortunately, I can't use poll :/.
I solved this issue by using select function inside a thread.
When the client performs some activity (ie writes or disconnects), the server can be setup to be notified of such. Look into using select(). When select() indicates that there is activity on the client socket, you should attempt to read from the socket. If recv() returns a status of zero (bytes), then that is the clue that the client disconnected.
Perhaps the following code will serve as a guide:
Code:
// open listen socket
...
// bind socket
...
// listen on socket
...
// accept connection(s)
while (true) {
int client_sock = accept(listen_sock, 0, 0);
if (client_sock > 0) {
handleClient(client_sock);
}
}
void handleClient(int sd)
{
fd_set read_sd;
FD_ZERO(&read_sd);
FD_SET(sd, &read_sd);
while (true) {
fd_set rsd = read_sd;
int sel = select(sd + 1, &rsd, 0, 0, 0);
if (sel > 0) {
// client has performed some activity (sent data or disconnected?)
char buf[1024] = {0};
int bytes = recv(sd, buf, sizeof(buf), 0);
if (bytes > 0) {
// got data from the client.
}
else if (bytes == 0) {
// client disconnected.
break;
}
else {
// error receiving data from client. You may want to break from
// while-loop here as well.
}
}
else if (sel < 0) {
// grave error occurred.
break;
}
}
close(sd);
}
P.S. The usage of select() is not paramount; the main thing is to examine the return value from recv() to determine if the client sent data or has disconnected. In the example above, select() will block until there is activity on the socket. If this is not desirable, then a timeout period (struct timeval) should be provided at the 5th arg to select(). Otherwise, calling recv() directly on a blocking socket will result in the app being blocked until the client performs some action.
Last edited by dwhitney67; 08-10-2010 at 05:42 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.