CSocket problem

I have a CWinThread that when run uses a CSocket object in Listen mode to wait for incoming calls.. after a specific time-out I wish to close
this thread and the socket.. but it keeps blocking, tried everything from
deleteing the socket (Assertion failure) to CancelBlockingCall and Close..
nothing works.. The problem is that the thread is used as a workerthread and has no window.. (this causes a exception on the Close() function..
The timeout of the CSocket object is also non-settable and so it keeps open forever.. The CSocket object is wrapped in a COM object.. but this gives no problems.. it can normally close, open, connect etc.. but when in listen mode
I can't exit the listen mode.. Really driving me nuts..

Am already thinking of changing everything to C++ Builder.. If I knew this would fix the problem..

The CSocket object is in a STREAM modus for synchronus transfer and this needs to be kept.. so please no answers stating to change to async modus.. (Tried that also, but listen keeps blocking and won't close or die..)

Thanks..
Jochen Rosenboom
Raistlin589Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sunrajCommented:
I am at the infant stage in socket programming. Please give me your mail id as i would like to know regarding socket programming.
But I have used multithreading in my project.
well...I do not know if the following would solve your problem. But let me share with you.

Are u specifying time out for the worker thread ?

The Assertion failure occurs inside the thread due to lot many reasons and one such thing is memmory leak. This is due to forceful termination of the thread and the memmory inside the thread is not properly deallocated.

If your problem is similar to one like above, then you have to synchronise your thread procedure.

Create an event object(in non signalled state) just before you create your thread.

when your time out period expires then set this event object to signalled state whose state is been monitored by the thread procedure. Then safetly close the socket handle.

regards!
0
MichaelSCommented:
Can you show us some code?
0
sun307Commented:
Hi !
There is no point to change everything to Borland C++, if you wish to have more conntrol over sockets you should use Raw win32 sockets API directly.
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Raistlin589Author Commented:
Thanks, but I already use a windows message to close the thread, and the problem is not closing the thread or memory leaks (I have only one CString object in the complete application that leaks once 83 bytes..)
The problem is simply that the Socket blocks the complete thread from running (So the windows handler in the Run statement will never be reached..) and I wish to stop this socket from blocking.. after it stops blocking (or preferably is closed for reuse) I simply use a PostThreadMesssage(WM_QUIT,0,0) on the thread to let it kill itself.. works fine (tested this code many times..) the socket itself is the problem, since closing it when it's in listen mode
creates a assertion on pstate->m_SocketWIndow
inside the socket..

0
MichaelSCommented:
2 sun307
100% agree :)
0
MichaelSCommented:
So why do you use blocking mode?
0
Raistlin589Author Commented:
Source of the thread (run part)

int C_ConnectorThread::Run()
{
      // If no user after 5 secs, destroy thread Yippie !@

      TRACE("C_ConnectorThread ONLINE\n");
      Ready.SetEvent();
      
      BOOL fDone = TRUE;
      MSG msg;

      while(fDone)
            {
            if((m_pNetworkOPL)&&(fDone))
                  {
                  BSTR TempString = _bstr_t(m_pIpAddress).copy();
                  m_pNetworkOPL->ConnectReceiveMode(&TempString,m_PortNr);
                  SysFreeString(TempString);
                  // contact user, give it the connected networkOPl back..
                  // nah.. just bleed it to death..
                  // without the release this one lives on inside the userthread
                  // long live da com commando's
                  
                  fDone = FALSE;
                  }
            while(PeekMessage(&msg, 0,  0, 0, PM_REMOVE))
                  if((msg.message == WM_QUIT)||(msg.message == WM_TIMER))
                        fDone = FALSE;
            Sleep(1000);
            }
      
      m_pOwner->RemoveConnectorThread(this);

      return 0;
}

source of the CSocket Com object (Connectreceive mode :

STDMETHODIMP C_NetworkOPL::ConnectReceiveMode(BSTR *apConnectionAddress, int aPortNr)
{
      AFX_MANAGE_STATE(AfxGetStaticModuleState())

      m_pConnectSocket = new CSocket();
      HRESULT hr = S_OK;
      BOOL Success = FALSE;
      m_PortNr = aPortNr;
      m_pConnectionAddress = new CString(*apConnectionAddress);
      
      if(m_pSocket)
            Success = m_pSocket->Create(m_PortNr,SOCK_STREAM);

      if(Success)
            {
            Success = m_pSocket->Listen(1);
            Success = m_pSocket->Accept(*m_pConnectSocket);
            }
      else
            hr = E_ABORT;
      
      if(!Success)
            {
            WriteError(1, &CString("ConnectReceiveMode"));
            hr = E_ABORT;
            }
      else
            {      
            WriteAction(&CString("ConnectReceiveMode"), &CString("Connect Receive Mode Success"));
            delete m_pSocketFile;
            m_pSocketFile = new CSocketFile(m_pConnectSocket);
            delete m_pArchive;
            m_pArchive = new CArchive(m_pSocketFile, CArchive::load);      
            m_SocketOpened = true;
            }

      return hr;
}

I'm not sure how to approach the API Sockets directly.. didn't find much help in MSDN about that topic.. if this could help fix the problem please show some source about it..

P.S. my mail address is jochen@satl.com

P.P.S. Close function of COM object only does
if(m_pSocket)
m_pSocket->Close()
0
Raistlin589Author Commented:
I use blocking mode, because these sockets need to speak to JAVA sockets and those are synchronous stream sockets.. when using synchronous mode some socket functions block..
0
ShaunWildeCommented:
The windows sockets are based on windows sockets and are message based and it usually better for you to treat them in this manner than it would if you tried to use them as you would standard sockets (UNIX based ones)

A better way to have a listening socket would be to create a CListeningSocket :public CSocket and handle the Accept in the OnAccept handler

see the following MS KB articles

Q175668
Q193101
Q192570

and maybe Q214396

at http://msdn.microsoft.com
0
Raistlin589Author Commented:
As stated the trouble is not the listen function, but making it stop while it's blocking...

handling the listen function with an accept is easy.. but am downloading the win32 sdk now..
will look into these things..

Thanks..
0
ShaunWildeCommented:
I don't think you are following me the way you have use the CSocket::Listen is wrong - you should handle all your accepts in the OnAccept handler see the examples for what I mean :)
0
Raistlin589Author Commented:
The trouble is not a correct listen or accept, but the blocking of the socket that even refuses it's own close then because it's inside a thread..
To Accept via the OnAccept is a improvement on my code, but it won't cure the main problem and that is that while the socket does the Listen(1);
if a CLose on this socket is called it asserts because it can't find it's socketwindow..

I do not wish to accept that socket but close it due to a time-out..
0
ShaunWildeCommented:
Ah have you set AfxSocketInit in the InitInstance of your CWinThread object ?
0
tchalkovCommented:
I made some experiments with CSocket and it seems that not Listen but Accept(..) is holidng the block. Have you confirmed that Listen is causing the block?
In the MFC Source Listen() simply calls the API function listen, while Accept is starting a loop.

So when you call Accept it starts a loop waiting for a incoming connection. In fact it calls a function PumpMessages, which is starting a loop which exits if there is a connection incoming or if a specified period of time has elapsed.

When PumpMessages loop is over it gets back to Accept function which again calls PumpMesssages
During PumpMesages loop if you call CancelBlockingCall() you can stop both loops.

The timeout for the inner loop is the member variable of the CSocket m_nTimeOut. It is public so you can access it even though it does not appear when you type in the Visual C++

If you call CancelBlockingCall from a different thread and this value is very small then it is not very likely that the other thread is in the PumpMessages Loop. And the flag which is used to interrupt blocking is initialized every time PumpMessages is Called.

There is no such problem if you call CancelBlockingCall from the same thread.

So a possible solution is to create your own class which inherits CSocket and to override the OnMessagePending function.

In that function check if the timeout has expired and if it has expired call CancelBlockingCall. This way you will call CancelBlockingCall in the same thread where you called Accept and it should work.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Raistlin589Author Commented:
Thanks everybody.. I think this will help..

I'll Split up the point under you all..

Thanks a lot !

JR
0
Raistlin589Author Commented:
Just search for your name to get the points..
(Your name is a question from me)

Comment to it and i'll accept it and award you with 100 pts..

thanks for the help..

JR
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.