LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-06-2010, 11:31 AM   #1
Lobinho
Member
 
Registered: May 2010
Distribution: Ubuntu
Posts: 72

Rep: Reputation: 18
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?

ps: I don't know sockets very well

Thanks in advance.
 
Old 08-06-2010, 02:40 PM   #2
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Actually, that's an interesting question - with a nontrivial answer.

Here are a couple of links. I'd also recommend getting Stevens: "Unix Network Programming"

Quote:
http://stackoverflow.com/questions/7...-server-socket

Q: How can I detect that a client has disconnected from my server?

A: Since there are no events available to signal when the socket is disconnected, you will have to poll it at a frequency that is acceptable to you.

http://forums.sun.com/thread.jspa?th...39297&start=15

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.

http://www.softlab.ntua.gr/facilitie...q-2.html#ss2.8

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).
'Hope that helps .. PSM

Last edited by paulsm4; 08-06-2010 at 02:41 PM.
 
Old 08-06-2010, 05:23 PM   #3
Lobinho
Member
 
Registered: May 2010
Distribution: Ubuntu
Posts: 72

Original Poster
Rep: Reputation: 18
Thanks for your reply paulsm4!

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 :/

Thanks anyway.
 
Old 08-06-2010, 05:52 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

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.

It's usually really as simple as that!

One other link that might help: Beej's Guide:

http://beej.us/guide/bgnet/

Your .. PSM
 
Old 08-09-2010, 04:27 PM   #5
Lobinho
Member
 
Registered: May 2010
Distribution: Ubuntu
Posts: 72

Original Poster
Rep: Reputation: 18
Hi paulsm4,

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.

http://linux.die.net/man/2/select

Last edited by Lobinho; 08-09-2010 at 04:30 PM.
 
Old 08-09-2010, 09:22 PM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Lobinho View Post
Hi paulsm4,

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.

http://linux.die.net/man/2/select
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.
 
1 members found this post helpful.
Old 08-10-2010, 02:28 PM   #7
Lobinho
Member
 
Registered: May 2010
Distribution: Ubuntu
Posts: 72

Original Poster
Rep: Reputation: 18
Thanks dwhitney67,

My current code is similar to your suggestion.
I didn't know the timeout parameter, it will be very useful.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
i want to connect mysql server from remote through TCP/IP not by unix socket dheerajjss Linux - Newbie 1 11-10-2008 06:32 AM
TCP Packet Dump in Server (Socket Progarmming) pooppp Linux - Networking 0 10-17-2008 07:52 AM
Server crash when client closed socket lrios Programming 14 05-14-2008 05:55 PM
Tcp client server development ptlchetan Programming 4 09-15-2006 04:49 AM
cannot read data at server socket, though client socket sends it jacques83 Linux - Networking 0 11-15-2005 01:58 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:49 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration