Server/Client Socket programming

 I am trying to write a server/ multi client application with visual studio 2010 c++ unmanaged, I can create the server fine and connect the clients fine but I can not successfully detect if a client has disconnected I have been trying to use FD_SET, FD_ISSET and select(..) but I still can not detect when a client has disconnected can anyone point me in the right direction or show me some sample code that dose show how to successfully detect if one of the clients has disconnected or lost its connection.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

While there is no way to automatically be notified when a client loses the connection, you can always call 'getpeername()' ( to check if you still have a connection, e.g.

BOOL CheckIfConnected(SOCKET s) {

  struct sockaddr addr;
  int len;
  len = sizeof(addr);
  return 0 == getpeername(s, (struct sockaddr*)&addr, &len);

Open in new window

nchannonAuthor Commented:
Hi jkr,
 I tried this approach also but when I physically disconnect a client getpeername still returned 0 on the socket number any idea why this would happen
My knowledge of select() is a little rusty, but when you call select(), is the socket that closed not returned in the SET that you passed for read notifications?  If it is; in that case, call recv() on it which should return -1 which means the socket is closed.

A much better way is to use IO completion ports, which do tell you immediately when a socket is closed; however their use is normally reserved for heavyweight servers requiring peak performance.
Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

the socket that closed not returned in the SET that you passed for read notifications?  If it is; in that case, call recv() on it which should return -1
if the socket was not closed the recv would block infinitely.

to check sockets whether they were still connected, you may periodically call select with minimal timeout, and on timeout  set the socket to non-blocking, then call recv. the return will be -1 (socket error) but the errno (or WSAGetLastError on windows) would return EWOULDBLOCK (WSAEWOULDBLOCK on windows) if the socket is still connected.

here the code for winsock to set the socket non-blocking

unsigned long iMode=1;
// reset to blocking mode
iMode = 0;

Open in new window

for Linux you would have

int oldflags = fcntl(sockfd, F_GETFL);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
fcntl(sockfd, F_SETFL, oldflags); 

Open in new window

note, from my experience disconnected clients don't make much troubles. if you often sent messages to all the clients connected or periodically would do some kind of heart-beat check, you immediately would find out whether they still are connected or not. the open socket handle in your server requires minimal overhead. so, beside you would run short on socket handles, it should be good, if you do the above check on idle time and after longer periods.  

nchannonAuthor Commented:
Hi Thanks for the reply, I have tried the blocking and non blocking approach as well but I still do not get -1 from recv() when I disconnect the client each time. Some times I get -1 but its not consistent eg: sometimes I get -1 from recv() immediately other times it could take 20 ~ 30 seconds or not at all.
how do make the disconnect? do you pull the cable?

nchannonAuthor Commented:
Hi Sara,
 Correct I physically disconnect the client, The client is connected via wifi local internal network on my router I just pull the wifi connection on the client side so the connection is fully terminated. This is what I need to do so the server can update its client list and remove any clients no longer connected.
nchannonAuthor Commented:
Hi I have come across  this link which works a dream but im am not familiar with using templates. I have adapted this example to an MFC dialog test app and can connect, receive and detect immediately when a client disconnects but as I mentioned I am not familiar with using templates and was wondering if someone can take a look at this ling and maybe point me in the correct direction on the best way to implement the templates to an MFC dialog and show who to send data to the clients using this approach.
Correct I physically disconnect the client
the problem with a physical disconnection is that the tcp/ip subsystem is not immediately recognizing that as a fatal error but handles it like a temporary failure. because of that connected server won't be notified even if they try to read from the client socket. you may check whether an orderly shutdown of the connection by the client would solve the issue and if yes, assess whether physical disconnection is a realistic use case which requires to being handled. as suggested, you could do a heart-beat check yourself, if you need a faster recognition.

was wondering if someone can take a look at this link
I looked on the link and as I see the template type used is only an option which allows to pass an own (class) object to the ClientSocket class:

The only limitation with the class/structure used as an attachment is: it should have a default (no arguments) constructer and a Clear() method (to perform internal cleaning). There are a few other requirements, but they will be described later
a bigger problem (as templates) for usage in a mfc dialog surely is that the solution is multi-threaded what means that the dialog (thread) cannot directly be server or client but only the user interface for either of the two.

to say more, you should describe what you want to do and what requirements you have. in any case the templates probably is one of the smallest problems.

nchannonAuthor Commented:
Hi Sara,
 Thanks for taking a look at the templates, What I am trying to achieve is the following:
I have developed my own wifi hardware device meaning I have built my own circuit board and developed the firmware my self that uses a wifi 2.4Mhz chip from Microchip, this is what I am referring to as the clients. These boards then connect via wifi to the server ( being an application running on win7 ) These client simply connect to the server via a router and send a connect status that include the mac address IP, firmware version, model name etc.. these are just text strings that the server receives which are then stored on the server in a vector array along with the socket that has been assigned to the client by the server this now allows the server to extinguish between clients for later use. The main server is a voice activated application for the disability where they say a command which is associated to a specific client (hardware device) eg: "turn on the TV in the bedroom" this in turn will tell the server that the client (hardware device ) is located in the bedroom with the associated socket assigned to it which then invokes the socket send(..) function and send the infra red pulse signal (binary) associated with turning the TV on to the client (hardware device) which in turns fires the infra red pulses that would normally be sent by the TV's remote control. this all works fine except if the client (hardware device ) drops its connection I need to detect this and warn the disable end user that there command will not be sent due to the device in the bedroom is no longer responding and to have it checked by an engineer or someone that understands the hardware eg: is it still got power to the client device.  
I think this explains what im trying to achieve by detecting the connection loss.
When I tried to use the template described above it detected the clients disconnection immediately and with my small amount of knowledge of templates I added a SendMessage(..) to the template header server_service.h see below:
  case _CLOSE:
                Log::LogMessage( L"CloseSocket request %d.\n", m_pSocket->GetSocket() );
                m_pSEvent->OnClose( m_pSocket, m_pOverlap, m_pServerSocket, m_pHIocp );
                // Make sure (double check) the socket
                // is closed.
                SendMessage(theApp.hwndMainParent, WM_SOCKET_DISCONNECT, 1, m_pSocket->m_ClientSock);
                m_pServerSocket->Release( m_pSocket );

            case _ACCEPT:
                m_pSEvent->OnAccept( m_pSocket, m_pOverlap, m_pServerSocket, m_pHIocp );
                SendMessage(theApp.hwndMainParent, WM_SOCKET_CONNECT, 0, m_pSocket->m_ClientSock);

            case _READ:
                m_pSEvent->OnReadFinalized( m_pSocket, m_pOverlap, m_dwBytesTransferred,
                    m_pServerSocket, m_pHIocp );

                SendMessage(theApp.hwndMainParent, WM_SOCKET_READ, (WPARAM)(char*)m_pOverlap->DataBuf.buf, m_pSocket->m_ClientSock);

Open in new window

when the event _CLOSE is fired I send the message along with the socket id back to the parent MFC dialog and processed the data accordingly eg: remove the client from the vector array which updates the server records. this is also the same for the event _READ this all works fine within my MFC app. I wasn't able to get the templates to work with child windows so this is why I pumped the message back to the the main parent dlg.

My main issue for me here is I could not get the event _SEND to respond mainly to my lack of understanding and using templates and this is where if possible I need help.
Thanks again and if you could add any light to this template I would be very grateful.
Kind Regards
below is the sample 'attachment' class used as template parameter for the socket classes

it has members  last action date/time and string buffer and functions Commit, Clear, ResetTime and GetTimeElapsed.

the socket classes will use an object of the template type to fill the string buffer with the data read from socket and to notify

struct Attachment {
    volatile time_t    tmLastActionTime;
    char            sString<BUFF_SIZE>;
    DWORD           dwStringSize; // current string's size

    Attachment() { Clear(); };

    bool Commit( DWORD dwBytesTransferred ) {
        DWORD dwSize = dwStringSize + dwBytesTransferred;
        if ( dwBytesTransferred <= 0 ) return false;
        if ( dwSize >= BUFF_SIZE ) return false;

        dwStringSize = dwSize;
        sString[dwStringSize] = 0;
        return true;

    // as requested by the API of the framework

    void Clear() { memset(this, 0, sizeof(Attachment) ); };

    // as requested by the API of the framework

    void ResetTime( bool toZero ) { 
        if (toZero) tmLastActionTime = 0;
        else {
            time_t    lLastActionTime;
            tmLastActionTime = lLastActionTime;

    // as requested by the API of the framework

    long GetTimeElapsed() {
        time_t tmCurrentTime;

        if (0 == tmLastActionTime) return 0;

        return (tmCurrentTime - tmLastActionTime);

Open in new window

to make the template classes real classes you simply do like (code also from  your link)

typedef ClientSocket<Attachment> MyCSocket;
typedef ServerSocket<Attachment> MySSocket;
typedef IOCPSimple<Attachment> MyIOCPSimple;
typedef ISockEvent<Attachment> MyISockEvent;
typedef ServerService<Attachment> MyServerService;

Open in new window

so, the template is nothing you have to care much about. it is a means to get notified immediately in the threads rather then waiting for events only and to get or put buffers from and to server class.

the following code from sample shows how the template class could be used:

// A template class allowing re-using of the memory blocks.
template<class T>
class QueuedBlocks {
    QMutex       m_qMutex;
    set< T* >    m_quBlocks;
    vector< T* > m_allBlocks;

    QueuedBlocks(int nInitSize = 1): 
        m_qMutex(), m_quBlocks(), m_allBlocks() {...};

    // get a free block from the queue, if one cannot be found
    // then NULL is returned

    T* GetFromQueue() {...};

    // get a free block from the queue, if one cannot be found
    // then a new one is created

    T* Get() {...};

    // Release the used block, place it
    // back to the queue. For performance reason,
    // we assume that the block was previously taken
    // from the queue.

    void Release(T* t) {...};

    // Return all the blocks ever allocated.

    vector<T*> *GetBlocks() {...};

    ~QueuedBlocks() {...};

Open in new window


QueuedBlocks<Attachment> blocks(100);

Open in new window

you would define a queue with maximum 100 'attachment' objects. the class has two containers - set and a vector - where it holds pointers to the Attachment objects. the set gives fast access by pointer (address), while the vector gives indexed access to the pointers such that the order the objects were created will be kept.

you can copy the code for the attachment as it is and - as far as I see - can ignore it until you learned more on how to use them for your purposes.

My main issue for me here is I could not get the event _SEND to respond mainly to my lack of understanding and using templates and this is where if possible I need help.
the _SEND isn't same category as _READ and _CLOSE. a send notification only can be fired if your program actively "sends" data to a client or server.

the send would be done calling MySServer::SendToSocket function (where MySServer is typedef'd as ServerSocket<Attachment>). you see a sample of the call in the sample function OnReadFinalized, which would be called after a read operation successfully was finished (probably the same as catching the _READ in your code).

virtual void OnReadFinalized( MyCSocket *pSocket, 
                MYOVERLAPPED *pOverlap, DWORD dwBytesTransferred, 
                MySSocket *pServerSocket, MyIOCPSimple *pHIocp ) {
        int nRet;
        DWORD dwSize, dwPos;
        char *temp;

        // finalize the filling of the buffer

        pSocket->GetAttachment()->Commit( dwBytesTransferred );

        dwSize = BUFF_SIZE - 1;
        dwPos = pSocket->GetAttachment()->dwStringSize;
        temp = pSocket->GetAttachment()->sString;

        nRet = pSocket->ReadFromSocket(    temp + dwPos, dwSize - dwPos );
        pSocket->GetAttachment()->ResetTime( false );

        if ( nRet == SOCKET_ERROR ) {
            pServerSocket->Release( pSocket );
        else if ( nRet == RECV_BUFFER_EMPTY ) {
            // means that dwSize - dwPos == 0, so send the data 

            // back to the socket

            nRet = pSocket->WriteToSocket( temp, dwSize );
            if ( nRet == SOCKET_ERROR ) {
                pServerSocket->Release( pSocket );

Open in new window

you see that the code uses a ClientSocket instance (MyCSocket) and the associated 'attachment' buffer to get the data read from socket and then writes back to client with pServer->WriteToSocket. if the send operation was successful, the OnWriteFinalized function was called by the server.

I didn't download the full source so far, so if you have detail questions to the code you would need to post the code you have problem with and refer to the line or statement where you have issues with.


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.