Link to home
Start Free TrialLog in
Avatar of morristoo
morristoo

asked on

CSocket::Accept, handle client in a thread

I'm creating a server that's listening on socket using "class CListenSocket : public CSocket". When CListenSocket::OnAccept fires, I use this code to create a socket to process the client request:

ClientSocket* pCSocket = new CClientSocket(this);
if (m_pLSocket->Accept(*pCSocket)) {
   .
   .

I realize CSocket is blocking, that's OK. I want to create a
UI thread or worker thread to process the client request. I can create a UI thread with this:

m_pClientThread = (CClientThread*)AfxBeginThread(RUNTIME_CLASS(CClientThread),   PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

How do I pass the pCSocket ptr to the UI thread? I've tried passing a ptr to the CListenSocket and doing the Accept in the thread after creating the client socket in the thread, doesn't work. I've tried a worker thread and passing pCSocket as pParm or even a ptr to CListenSocket as pParm. I  even tried passing the handle of the socket and trying an Attach in the new thread.

In general: How does one create a server application using the CSocket class that listens on a socket in the main app thread, and creates a client socket that is processed in a separate thread? That is "one thread per client". No examples can be found that process client requests in separate threads. The only CSocket example I've found is the CHATTER example and it's not multithreaded.

Avatar of morristoo
morristoo

ASKER

Adjusted points to 150
I failed to mention I can make the CSocket class work just fine as long as no threads are involved. I also failed to mention the primary symptoms when a worker thread is involved is the Accept or attempts to send/receive are ignored. If I use a UI thread, I get access violations. I understand worker threads have no message pump, and that's probably why socket calls have no effect in a worker thread.

I also understand as a general rule a thread can only access MFC objects it creates. That's why I tried creating the CSocket MFC class in the thread. I've read the docs that state a way around this is to pass individual handles rather than C++ objects and add the handles to the temporary map using FROMHANDLE or to use ATTACH to add the object to the thread's permanent map. I've tried these techniques with no success possibly because I can't find any details on techniques to do this. I suppose all I really need is an example along these lines.

I also realize the MFC is a poor choice for writing socket code and to 'do it right' I should be coding at the winsock level, or at the very least using CAsyncSocket. My justification for wanting to use CSocket shouldn't cloud the question. I can explain my justification for using CSocket, if that's required.
Adjusted points to 200
Failed to mention I'm using NT4 Server and VC++ 5.0.
Adjusted points to 210
Can you explain the whole process more clearly ? Have you tried handling the connection in the same thread, then create a new thread with a new CListenSocket for new incoming connections ?

Re: 1st question...:
Perhaps I have done a poor job of explaining the initial concept. I was attempting to be as terse as possible, yet relay as many details as possible. I'll give it another go... I have derived a class from CListenSocket to listen on port 700 for a connection. When a connection is made, the OnAccept event fires in the CListenSocket class. At this point the idea is to create a new socket to handle the client's request such that the CListenSocket class is free to accept another client request. I don't want to be required to complete the client request before I can accept another connection. If this were a Unix server I would use fork() to create a child process to handle the client request, while the main process continued to wait for a new connection. I would use fork() after each successful client connection.

If you have the Visual Studio Library '97 CD, reference this URL: mk:@ivt:backplat/D3/S1CB9.HTM. It will point you to an article entitled "Writing Great Windows NT Server Applications". Half way down in that aricle the author suggests five options for handleing socket requests. They are:
1. Single thread, single client. 2. Single thread, multiple clients. 3. One thread per client. 4. Worker threads with synchronous I/O and 5. Worker threads with asynchronous I/O. My question relates to how to implement option #3 or #4, assuming #5 is more trouble than it's worth. I've attempted both #3 and #4.  I can't find an example of 3, 4, or 5. I can implement option #1 or option #2, that's easy, only one thread. The issue in implementation of #3 or #4 is how to a pass a usable reference for the newly created client socket to the new thread.

Re: 2nd question ...
Yes, I can make this work with one thread. There's lots of examples of how to do that. See the CHATTER example supplied with VC++ 5.0. Using a single thread is covered in  options #1 and #2 in the article mentioned above. I'm not sure I understand the concept of creating a second CListenSocket class and using the existing CListenSocket to process the client request. I'm not sure that's possible and if it were, it still wouldn't solve my problem of how to process a client request in a separate thread.

(By the way can anyone you me how to acquire more points? I'm willing to buy the points and up the number of points this question is worth. I guess I'll keep playing the quiz game and grabbing points a little at a time.)

All I need is an example of a NT based TCP/IP service application that uses CListenSocket/CSocket (MFC classes) and listens on a port for a client request. When the request is detected and accepted, the application processes the request with an in-process thread. I really believe this is possible. There are many references in the literature that suggests using the blocking CSocket with multiple threads.

Never mind... I finally figured how to accept the socket and process the request in a separate thread. If anyone was researching this, the secret is to use a UI thread, but don't start it with the AfxBeginThread() function.
ASKER CERTIFIED SOLUTION
Avatar of mbhakta
mbhakta

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
what kinda answer is this.  i want my points back.