Thread: Listening socket and thread problem

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    23

    Listening socket and thread problem

    To outline the problem: I have a socket server listening in a seperate thread to the main program. The socket accepts new connections and deals with them, then listens again. It is in a while loop.
    When I click on the button to shut down the socket server, I can not figure out a way to close the thread with the listening socket in it, because it is stuck on the line where it listens. Only after I open a connection and it runs though the code again and realises that run is set to false does the thread close.
    This is obviously a problem as when I click shutdown server I want the server to shut down now, not after the next connection!
    rough outline:
    Code:
    (inside the thread)
    while 1
    {
        socket->listen
        (deal with connection)
        if run is false return 0
    }
    I am using winsock and windows CreateThread if that is important.

    So, does anyone know a way to either run the listening socket differently, or shut down the thread somehow? I wanted to avoid TerminateThread as it doesn't clear everything.

    Thanks a lot in advance for all your help.
    esaptonor

  2. #2
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    It's been a little while since I've done it, but I believe that closing the socket will release it from the listening function, and should allow you to escape the loop. At that point the thread should complete normally.

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    23
    Hmm...doesn't work. It causes the program to 'abnormally terminate' or something.
    I have realised that the socket is not just listening, it is running the accept function, which I presume waits until something connects to it.
    Can a socket not be closed if it is running accept? or is this because I am trying to close it from a different thread to the one it is in (because the thread it is in is stuck on that line...)

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    When listen exits and you call accept - do you check the reason for exiting?
    I think listen exist with error (something like SOCKET_DESTRUCTED) and you still call the accept instead of exiting thread - this is source of the crash
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    You could also call TerminateThread() from your exit sequence. AFAIK that will instantly kill the thread regardless of its state.
    Last edited by abachler; 05-29-2007 at 12:02 PM.

  6. #6
    If you do a search on google for "non-blocking sockets" or "asynchronous sockets" you will find your options and your answers.

    Accept() blocks execution of your thread until its completion. {southern accent] That thers yer problem raght ther.
    "There's always another way"
    -lightatdawn (lightatdawn.cprogramming.com)

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    1

    The way I used to terminate the thread listening on the socket

    To force the listening thread terminate in a safe way I made the boolean m_bIsShuttingDownflag known to both main and listening thread. In addition, my main thread knows the port m_sLocalPort listening thread listens to. Pressing shutdown button makes the main thread set this flag to TRUE, connect to the port just to make listening thread exit the listen() function. Immediately after accept() the m_bIsShuttingDownflag is checked, and if it is set, the listening loop exits, the listening socket m_listen_socket is closed, and whatever resources being used by the listening thread are released. This way you should not wait for the next connection to make your server shutdown, because you provoke its shutdown by making the last connection yourself from the main thread.
    Important: in the main thread you should wait on the listening thread's handle m_hListeningThread in case the main thread is going to be shut down as well. If you don't synchronize, you risk to crash your app.
    The code snippet:
    ----The main thread------
    Code:
    CloseListeningThread();
    where the function CloseListeningThread() is defined like:
    Code:
    int CloseListeningThread()
    {
    	int iRetVal = SOCKET_ERROR;
    	if(m_hListeningThread)
    	{
    		// Convert nnn.nnn address to a usable one 
    		unsigned int addr = inet_addr("127.0.0.1");
    		struct hostent *hp = gethostbyaddr((char *)&addr,4,AF_INET);
    		if (hp != NULL ) 
    		{
    			struct sockaddr_in proxy; // server's address structure
    			memset(&proxy,0,sizeof(proxy));
    			memcpy(&(proxy.sin_addr),hp->h_addr,hp->h_length);
    			proxy.sin_family = hp->h_addrtype;
    		
    			proxy.sin_port = htons(m_sLocalPort);
    
    			m_bIsShuttingDown = TRUE; // tell the listening thread it is going to be terminated
    			SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    			if(INVALID_SOCKET != s)
    			{
    				iRetVal =  connect(s,(struct sockaddr*)&proxy,sizeof(proxy));
    				if(iRetVal == 0)
    				{
    					// Important: wait a bit until listening thread exits
    					WaitForSingleObject(m_hListeningThread,5000);
    				}
    				else
    				{
    					TCHAR szMsg[MAX_PATH];
    					HRESULT hr = StringCchPrintf(szMsg, sizeof(szMsg), 
    						_T("CloseListeningThread: connect() failed with error %d"),WS2_WSAGetLastError());
    					Trace(szMsg);
    				}
    			}
    		}
    	}
    	return iRetVal;
    }
    ---The listening thread-----
    Code:
    TCHAR szMsg[MAX_PATH];
    int fromlen;
    struct sockaddr_in from;
    
    // listening loop snippet
    while(1) 
    {
    	fromlen =sizeof(from);
    	m_sckLatestClient = accept(m_listen_socket,(struct sockaddr*)&from, &fromlen);
    	if (m_sckLatestClient != INVALID_SOCKET) 
    	{
    		if(!m_bIsShuttingDown)
    		{
    			// DO whatever the server needs to do upon being connected to
    		}
    		else
    		{
    			break; // exit the listening loop to shut down
    		}
    	}
    }
    closesocket(m_listen_socket);
    // Here release whatever other resources the listening thread was using

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Asynchronous Socket Thread closes after first receive
    By AndreasS in forum C# Programming
    Replies: 1
    Last Post: 04-16-2009, 08:31 AM
  2. Terminating secondary thread from another thread
    By wssoh85 in forum C++ Programming
    Replies: 13
    Last Post: 12-19-2008, 05:14 AM
  3. Problem with sigwait
    By pio in forum Linux Programming
    Replies: 3
    Last Post: 11-29-2007, 09:05 AM
  4. listening loop problem
    By Bleech in forum Networking/Device Communication
    Replies: 4
    Last Post: 04-08-2007, 02:33 AM
  5. socket blocking problem
    By killerbyte in forum Linux Programming
    Replies: 2
    Last Post: 05-21-2006, 03:25 PM