Solved

MFC CSocket doesn't call OnAccept

Posted on 2004-04-16
14
1,372 Views
Last Modified: 2011-08-18
I have written a little test app for a CSocket project, but I cannot get it to call my OnAccept method

My CSocket based class is defined as follows:
class MySock : public CSocket
{
public:
   MySock(){};
   virtual ~MySock(){};

   virtual void OnAccept( int nErrorCode )
   {
      std::ofstream ofs( "c:\\zzzzz_socky.out", std::ios::app );
      ofs << nErrorCode << std::endl;
      ofs.close();
   }
};

I am using it as follows:
AfxSocketInit();
MySock * pSocket = new MySock;
BOOL bOK = pSocket->Create( 12345, SOCK_STREAM );
char szBuff[1024];
pSocket->Listen();
MySock AccSock;
pSocket->Accept( AccSock );
AccSock.Receive( szBuff, sizeof( szBuff) );
delete pSocket;

I send it a packet, which is received fine, but MySock::OnAccept is never called and I don't understand why, I assume I have missunderstood how this is supposed to work.
0
Comment
Question by:duncanlatimer
  • 6
  • 5
14 Comments
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10842188
Because of that MSDN doc - see below - i would assume that you have to omit the call of Accept() and wait to be called from the framework after listening. So move the code

MySock AccSock;
pSocket->Accept( AccSock );
AccSock.Receive( szBuff, sizeof( szBuff) );
delete pSocket;

to the OnAccept function.

------------------------------- FROM MSDN  -------------------------------------------------------------------
CAsyncSocket::OnAccept
virtual void OnAccept( int nErrorCode );

Parameters

nErrorCode

The most recent error on a socket. The following error codes applies to the OnAccept member function:

0   The function executed successfully.


WSAENETDOWN   The Windows Sockets implementation detected that the network subsystem failed.
Remarks

Called by the framework to notify a listening socket that it can accept pending connection requests by calling the Accept member function. For more information, see the articleWindows Sockets: Socket Notifications in Visual C++ Programmer's Guide.

---------------------------------------------------- END MSDN ----------------------------------------------------------------------------------------

Regards, Alex

(Sorry don't know much about CSockets as i use the  native socket interface. Tell me if you want to know to use this instead of MFC sockets).

0
 

Author Comment

by:duncanlatimer
ID: 10842552
Thanks, I also would normally have used winsock, but I thought I'd give CSocket a blast this time round, what I was expecting was for OnAccept to be called prior to Accept getting executed, I am only calling Accept in my code snippet to get the socket to block, once I have the basic principle working I will be creating a new thread in OnAccept to Accept the incoming connection. I think I have made a fundamental error in my understanding of how CSocket works, if someone can point out my error I'll be away.
0
 

Author Comment

by:duncanlatimer
ID: 10842595
I wasn't really expecting to have to call Accept to make the socket block, but if I didn't call it it didn't block.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10842848
>> but if I didn't call it it didn't block.

Actually the default is a blocking socket. So if you make a recv() or accept() to socket you will wait infinetly. You could make the socket non-blocking by calling ioctl(...FIONBIO). There is an analogue function with CAsyncSocket i know. Then on every read or accept you - normally - will return with error WSAEWOULDBLOCK, indicating there is nothing to accept or read. you could do that in a OnTimer() function within message loop until you get some client to accept or some data to read. With CSocket - as i unterstand it - you have a synchronous access to a blocking socket. That would mean to listen() and then - trusting the framework - wait until the callback OnAccept() or OnReceive() is called to signal you can accept/receive from socket without having to fear to block.

Regards, Alex
0
 

Author Comment

by:duncanlatimer
ID: 10842894
I've sort of sussed it out, I put the code in a single document interface application and just called listen, then when I sent a packet OnAccept was called just fine, I basically had it in the wrong framework I think.

I would like to know how to use CSocket in a console type application, if anyone knows.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10842963
>> I will be creating a new thread in OnAccept()

If OnAccept() is called by the framework you don't have to create a thread. You could wait on the accepted new socket using the callback OnReceive()  similar to OnAccept. Then, your read socket is checked wile the message loop is running - i suppose in CWinThread::OnIdle() - for incoming messages and if some exist OnReceive() get called.

With threads, you normally have an own thread for any new connection - accepting as  a server or sending/receiving as a client. Then you set the socket to non-blocking and run an infinite loop where you always check three things: (1) the non-blocking socket if there is any to accept/read, (2) an exit flag maybe set from the GUI thread, (3) if there are any messages to send.

For all this, you may use CAsyncSocket. However, then all threads need an own message loop.

Regards, Alex
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:duncanlatimer
ID: 10857578
Surely if I don't create a new thead to accept each connection attempt I won't be able to deal with concurrent connections?
My basic idea is as follows:
Create listening socket and wait for connection attempts.
When someone tries to connect OnAccept will be called and I will create a thread to handle the connection, i.e. call Accept et al.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10857884
>> When someone tries to connect OnAccept will be called and I will create a thread to handle the connection,

Yes, that's a good practice. You'll get a new socket when accepting a client connection and the thread should handle sending messages and receiving messages. The main thread is still in listening mode and will get called again if there is another client to accept.

>>  i.e. call Accept et al

The thread shouldn't handle a further accept. That's the job of the first thread (main thread) that received OnAccept() callback.

Regards, Alex

0
 

Author Comment

by:duncanlatimer
ID: 10857893
Cheers
0
 

Author Comment

by:duncanlatimer
ID: 11087731
As itsmeandnobodyelse didn't actually answer the question (I answered it myself) why should they get the points? For 50 points I'm not going to argue too strongly!!
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 11087941
If duncanlatimer wants his points back there isn't any objection from me.

Regards, Alex
0
 
LVL 1

Accepted Solution

by:
GhostMod earned 0 total points
ID: 11227171
PAQed, with points refunded (50)

GhostMod
Community Support Moderator
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now