15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


multithreaded server using sockets

Adam Solesby -- adam@solesby.com
Tuesday, December 17, 1996

Environment: NT 4.0, NT 3.51, VC++ 4.0

I am trying to write a multithreaded server that uses a seperate thread to
service each client. I'm usings sockets and trying to use CAsynSocket. I am
having difficulty determining what should be handled by the main UI thread
and when (and exactly how) control should be given to the worker thread.
Does anyone with more experience have a pointer to some sample code or
other advice?

Thanks, Adam Solesby.
--
==========================================================================
Adam Solesby              adam@solesby.com            615.269.7836  [home]
http://www.melt.net   solesbag@vuse.vanderbilt.edu    615.314.2500 [pager]
==========================================================================



Phil Daley -- pdaley@relay.com
Thursday, December 19, 1996

[Mini-digest: 2 responses]

At 10:11 AM 12/17/96 -0600, Adam Solesby wrote:
 
>Environment: NT 4.0, NT 3.51, VC++ 4.0
>
>I am trying to write a multithreaded server that uses a seperate thread to
>service each client. I'm usings sockets and trying to use CAsynSocket. I am
>having difficulty determining what should be handled by the main UI thread
>and when (and exactly how) control should be given to the worker thread.
>Does anyone with more experience have a pointer to some sample code or
>other advice?

Typically the main thread has a (defined) listen socket for the purpose of clients calling in.  When the client calls in, then the server creates a new socket to service the client. Once the socket is connected, the socket is handed over to the new thread to service the client.

99% of errors happen during connection, so it is much simpler to make sure everything worked before starting a new thread.  This does cause a small delay where the server is unavailable to accept new clients.  In real life, this is never noticed.  It can be aggravated by a QA test where 25 people attempt to log in simultaneously.  Even Unix bogs down under these conditions.

BTW, VC++ 4.0 has major errors in the CSocket code.  You will never get it to work.  We started a while ago and rewrote the socket classes.  I think 4.2 has fixed the problems.


Phil Daley          Relay Technology
http://www.conknet.com/~p_daley


-----From: Tim Robinson 

At 10:11 12/17/96 -0600, you wrote:
>Environment: NT 4.0, NT 3.51, VC++ 4.0
>
>I am trying to write a multithreaded server that uses a seperate thread to
>service each client. I'm usings sockets and trying to use CAsynSocket. I am
>having difficulty determining what should be handled by the main UI thread
>and when (and exactly how) control should be given to the worker thread.
>Does anyone with more experience have a pointer to some sample code or
>other advice?

I had to do something similar myself.  Unfortunately, it's not so easy to
pass a CAsyncSocket to a thread.  The library does some cleanup to make sure
that the creating thread does the destroy.  The solution is pretty easy,
though.  I presently have my main app listen for connects and accept a
non-sub-classed CAsyncSocket.  I pick a few accounting particulars out of
the socket, then get the socket handle using CAsyncSocket::Detach and pass
that to the thread startup code.  The thread then creates its own instance
of a sub-classed CAsyncSocket and does a CAsyncSocket::Attach (using the
aforementioned handle) to bring it alive.

Something like this (function/class names changed to protect the innocent):

void CListen::OnAccept( int )
   {
   CAsyncSocket socket;
   SOCKADDR_IN addr;
   int len = sizeof(addr);

   if ( Accept( socket, (SOCKADDR*)&addr, &len ) ) {
      socket.AsyncSelect( FD_CLOSE | FD_READ | FD_WRITE );
      // other local accounting snipped
      CMyThread *thread = new CMyThread( socket.Detach() );
      VERIFY( thread->CreateThread() );
      }
   else  // error handling snipped
      ;
   }

CMyThread::CMyThread( SOCKET s ) : m_hSocket(s) {}

BOOL CMyThread::InitInstance() {
   m_Socket = new CMySocket( ... );
   m_Socket->Attach( m_hSocket );
   }

| Tim Robinson, Esquire          | Liberty  means responsibility. |
| timtroyr@ionet.net             | That is why most men dread it. |
| http://www.ionet.net/~timtroyr |            George Bernard Shaw |





| Вернуться в корень Архива |