Thread: Make accept() stop

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    102

    Make accept() stop

    Ok, I have a program that creates threads that each listen on a port, The problem is that when I call accept() in the thread, It means I can't close the thread without calling TerminateThread(), which I've been advised in the past not to do. So what I'm asking, is there a way that I can cause accept() to end? I tried calling WSACleanup() from my main thread, but It doesn't effect anything?
    I just need a way to cause an error within accept() to make it stop.
    thanks

  2. #2
    'AlHamdulillah
    Join Date
    Feb 2003
    Posts
    790
    what you are looking at is one of the problems of non-blocking sockets. This can easily(and I do mean easily) be resolved if you poll a socket to check to see if there is any incoming data, if so then you can try to use accept(a socket listening for connections should do just that, and not try to listen for other data, IMO).
    there used to be something here, but not anymore

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    That is one of the problems of blocking sockets. Two options are, port your program to using asynchronous sockets, or do the polling thing that EvBladeRunnervE suggested (look into select()).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Just for kicks I wrote an abortable accept function. It is untested so let me know if it works. Error checking could be better.
    Code:
    /*
     * Works like the normal accept(), except that it takes an abort event. When this event is 
     * signalled this function will return INVALID_SOCKET immediately.
     */
    SOCKET AbortableAccept(SOCKET s, struct sockaddr* addr, int* addrlen, HANDLE hEventAbort)
    {
    	SOCKET sockRet;
    	HANDLE hEvents[2];
    	ULONG  setting[2] = { 0, 0 };
    
    	if (hEventAbort == NULL)
    	{
    		/* Normal, non-abortable accept(). */
    		return accept(s, addr, addrlen);
    	}
    
    	hEvents[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* Will be signalled for an incoming connection. */
    	hEvents[1] = hEventAbort; /* Will be signalled by another thread to abort the accept operation. */
    
    	WSAEventSelect(s, hEvents[0], FD_ACCEPT); /* Puts socket in non-blocking mode and 
    	                                           * tells windows to signal hEvents[0] when the
    	                                           * accept() has completed or an error occurs. */
    
    	if (WaitForMultipleObjects(2, hEvents, FALSE, INFINITE) == WAIT_OBJECT_0)
    	{
    		/* An incoming connection has arrived or a network error has occurred. */
    		sockRet = accept(s, addr, addrlen);
    	}
    	else
    	{
    		/* Abort event was signalled or WaitForMultipleObjects error. */
    		sockRet = INVALID_SOCKET;
    	}
    
    	/* Cleanup event signalling */
    	WSAEventSelect(s, hEvents[0], 0);
    	CloseHandle(hEvent);
    
    	/* Put sockets back into blocking mode */
    	ioctlsocket(s,       FIONBIO, &setting[0]);
    	ioctlsocket(sockRet, FIONBIO, &setting[1]);
    
    	return sockRet;
    }
    
    
    
    /* Sample usage. */
    
    /* Create a global manual-reset event. */
    g_hAbortEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    /* Start an abortable accept. */
    sock = AbortableAccept(s, (struct sockaddr*) &addr, &addrlen, g_hAbortEvent);
    
    /* In another thread - signal the event and abort the accepts that are using it. */
    SetEvent(g_hAbortEvent);

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    102
    So, Hunter2, could you please point me to a link that explains how to convert my program to use asynchronous sockets?

    anonytmouse, even though that code looks very interesting, I think it's a little ahead of me at the moment.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I'm pretty sure there's some links to tutorials at the top of this forum, most of them will deal with asynchronous Winsock to some extent.

    Here's Johnnie's tutorial, it covers the very very basics of using asynchronous winsock at the bottom of the tutorial.. you can probably find more if you search on Google.
    http://www.hal-pc.org/~johnnie2/winsock.html
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Apr 2004
    Posts
    102
    Ok, so I got it semi-working. If I only call WSAAsyncSelect() once, it's fine. But if I try to call it again for another socket, it fails. why can this be?

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I don't think that should happen. Can you post some code?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    Registered User
    Join Date
    Apr 2004
    Posts
    102
    Strange, It's now working because I took out a piece of unrelated code. Is there anyway to get the port back from a socket?
    I tried:

    Code:
    sockaddr_in test;
    					SOCKET sock = accept((SOCKET)wParam,(sockaddr*)&test,&x);
    wsprintf(addstrbuff,""Port:%d ",(int)ntohs(test.sin_port));
    MessageBox(0,addstrbuff,"",0);
    But the port is completely wrong?

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    What are you getting as the value for the port? At a glance, your code looks correct. Also make sure that x is initialized to sizeof(struct sockaddr) before you pass its address to accept().

  11. #11
    Registered User
    Join Date
    Apr 2004
    Posts
    102
    I usualy get a random number above 3000, If the first random number is 3980 the next will be 3981, and so on, no matter which port it is.

  12. #12
    Registered User
    Join Date
    Apr 2004
    Posts
    102
    Just figured it out, It's giving me the remote port, not local. Is it possible to get the local port at which a connection is established?

  13. #13
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Typically, for a server socket, the local port is whatever you bound it to. However, if you need a function to retrieve this information, you can use getsockname().

  14. #14
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    Simply closing the socket from another thread will cause accept() to return.

  15. #15
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    random: Johnie2 updated his tutorial? Nice job man. I remember him asking me about why I called it incomplete once. Impressively better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why does my prog just stop?
    By Queatrix in forum Windows Programming
    Replies: 4
    Last Post: 03-01-2006, 05:12 PM
  2. Win32 Common Controls in C++, how do i make and use them?
    By C+noob in forum Windows Programming
    Replies: 6
    Last Post: 01-09-2006, 11:53 AM
  3. want to make this small program...
    By psycho88 in forum C++ Programming
    Replies: 8
    Last Post: 11-30-2005, 02:05 AM
  4. Make Cortana Stop Kicking Me!!!???
    By drdroid in forum C++ Programming
    Replies: 6
    Last Post: 02-27-2003, 05:27 PM
  5. how to make files
    By quiksilver9531 in forum C++ Programming
    Replies: 6
    Last Post: 02-22-2002, 06:44 PM