Solved

MFC CSocket doesn't call OnAccept

Posted on 2004-04-16
14
1,367 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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
C++ - Convert a wString to char * 9 438
MSVCR80.dll crash 2 126
computer science syllabus 3 53
Problem with SqlConnection 5 124
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

744 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

12 Experts available now in Live!

Get 1:1 Help Now