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 |
| Вернуться в корень Архива
|