Raistlin589
asked on
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
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
Can you show us some code?
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.
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.
ASKER
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..
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
creates a assertion on pstate->m_SocketWIndow
inside the socket..
2 sun307
100% agree :)
100% agree :)
So why do you use blocking mode?
ASKER
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->ConnectRece iveMode(&T empString, 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->RemoveConnectorT hread(this );
return 0;
}
source of the CSocket Com object (Connectreceive mode :
STDMETHODIMP C_NetworkOPL::ConnectRecei veMode(BST R *apConnectionAddress, int aPortNr)
{
AFX_MANAGE_STATE(AfxGetSta ticModuleS tate())
m_pConnectSocket = new CSocket();
HRESULT hr = S_OK;
BOOL Success = FALSE;
m_PortNr = aPortNr;
m_pConnectionAddress = new CString(*apConnectionAddre ss);
if(m_pSocket)
Success = m_pSocket->Create(m_PortNr ,SOCK_STRE AM);
if(Success)
{
Success = m_pSocket->Listen(1);
Success = m_pSocket->Accept(*m_pConn ectSocket) ;
}
else
hr = E_ABORT;
if(!Success)
{
WriteError(1, &CString("ConnectReceiveMo de"));
hr = E_ABORT;
}
else
{
WriteAction(&CString("Conn ectReceive Mode"), &CString("Connect Receive Mode Success"));
delete m_pSocketFile;
m_pSocketFile = new CSocketFile(m_pConnectSock et);
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()
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->ConnectRece
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->RemoveConnectorT
return 0;
}
source of the CSocket Com object (Connectreceive mode :
STDMETHODIMP C_NetworkOPL::ConnectRecei
{
AFX_MANAGE_STATE(AfxGetSta
m_pConnectSocket = new CSocket();
HRESULT hr = S_OK;
BOOL Success = FALSE;
m_PortNr = aPortNr;
m_pConnectionAddress = new CString(*apConnectionAddre
if(m_pSocket)
Success = m_pSocket->Create(m_PortNr
if(Success)
{
Success = m_pSocket->Listen(1);
Success = m_pSocket->Accept(*m_pConn
}
else
hr = E_ABORT;
if(!Success)
{
WriteError(1, &CString("ConnectReceiveMo
hr = E_ABORT;
}
else
{
WriteAction(&CString("Conn
delete m_pSocketFile;
m_pSocketFile = new CSocketFile(m_pConnectSock
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()
ASKER
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..
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
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
ASKER
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..
handling the listen function with an accept is easy.. but am downloading the win32 sdk now..
will look into these things..
Thanks..
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 :)
ASKER
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..
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..
Ah have you set AfxSocketInit in the InitInstance of your CWinThread object ?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks everybody.. I think this will help..
I'll Split up the point under you all..
Thanks a lot !
JR
I'll Split up the point under you all..
Thanks a lot !
JR
ASKER
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
(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
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!