|
I have this thread that sits doing recv()'s and kicking out data packets; the main application is running in another thread getting on with doing its stuff.
So:
is my "recv() thread" eating lots of CPU time, or is this a nice efficient way of doing things?
(& can you direct me to a webpage or something that actually says this is the case! I've looked at about a million descriptions of what blocking IO is and none tell me what I want..)
and:
any idea how i can terminate my "recv() thread"?
currently if a client is connected, the recv() function blocks until the client sends something; this is great until i want to kill my server application - if the client is still connected, the server's "recv() thread" currently wont die.
(I know I could for example send() to the client & tell it to send() me back some data to wake the recv() function up, but that seems a little poxy).
Thanks in advance to anyone who takes the time to reply
|
|
|
|
|
Unless there is something you are not telling us, such as you have set the socket non-blocking, recv should block and not eat up any significant CPU time until there is data available. Do you have some indication that your recv thread is eating lots of CPU time?
As for your second question, I was going to tell you about WSACancelBlockingCall, but I see it is no longer supported. (I wonder what they were thinking. This was a useful mechanism.) You might try closing the socket from another thread (your main thread, for instance) to see if that unblocks the recv. The only alternatives that I can think of involve using some form of select().
|
|
|
|
|
When recv is blocked waiting for more data, it does so in an efficient manner, you shouldn't note an increase in CPU usage --so if that's the problem, it lies somewhere else.
As for how to terminate a blocking recv a simple and dirty way is to closesocket the socket the call is waiting on (recv will return with an error.)
If you have time and interest in redisigning your app, some other types of sockets are possible:- Non-blocking sockets, handled thru
select .
- Asynchronous sockets managed thru windows messages (see
WSAAsyncSelect .)
- Asynchronous sockets managed thru events (see
WSAEventSelect .) All of them are better fit to make up a design involving premature termination.
You can find much more (and better) info than fits in this post in Warren Young's Winsock Programmer's FAQ.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I think this is an efficient way, but I cannot point you to a web page that says so. I do this all the time, and cpu usage is miniscule.
Re: recv(): I have a loop in a separate thread that does a socket accept(), and I have a similar problem--how do I tell that thread to stop? When I'm ready to stop, in the main thread I close the socket that the accept is waiting on. The accept returns with an error. That thread checks to see if the main thread has asked it to stop (global variable accessed through a function), and ends.
That sounds pretty severe to me (that is, closing the socket out from under the accept), but it seems to work well. I suspect it might work fine with the recv, as well.
Hope this helps.
mflanagan@MJFlanagan.com
|
|
|
|
|
Thanks for the info!
Re: your accept() problem/ solution:
I had this problem too:
My CSocketServerThing class starts up a thread in its constructor;
the thread sits doing a socket accept()
now, say no one connects, and my CSocketServerThing destructor is called - it had no way to terminate its "accept()-blocked" thread;
My solution (i say "my", i nicked it off a newsgroup is to have my destructor:
set a boolean that the "accept()-blocked thread" can see to indicate destructor has been called;
create a temporary client that connects to the blocked "accept()" thread's socket
(this unblocks the accept() thread, which then checks the bool: "ohno!" it thinks, "destructor call! I wont bother doing anything else then!" and so my thread terminates which is what i want)
close my temporary client
This means the accept() call does its stuff (instead of having the socket closed from under it) and the thread terminates gracefully.
I'm not too good @ explaining... I can send you the (currently hackish) source if you want, mail me on uviolets@icqmail.com if interested.
Thanks again,
5th
|
|
|
|
|
Thanks everyone so far, nice to see someone out there understands this sockets guff
re my "recv() thread": no, it doesnt appear to be eating CPU cycles, everything looks fine
(
my reason for asking was I have a very fast PC and its not doing much else other than running my sockettest program ATM, so i was worried I was using CPU and not noticing (I didnt want it to come back & bite me later on when I'm doing lots of intensive compression stuff )
)
- so I'm happy to have you confirm its a nice efficient way of doing stuff.
re killing the thread: i thought of just doing a close(), but it seemed a little harsh, but if thats what you reccomend I'll give it a go (main worry was handle/ resource leakage: I've no tools to show such leaks & I dont personally know enough about sockets to know if principle is sound)
Thanks again & I'll keep an eye on the thread in case anyone else has further gems of wisdom
|
|
|
|
|
I have the CMainFrame class derived from the CMDIFrameWnd and I'm trying to handle the WM_SIZE message. I added the function to my code and without any modifications to the code provided by the wizard, my application acts all screwy. By that I mean, I have the Main Fram maximize on startup but the application doesn't draw correctly. In Theory, I guess it's maximized since the Minimize, Resize, and Close buttons are in the upper right hand corner of my screen and I can grip the frame in the bottom right hand corner to resize the application, but the window seems to think it's not maximized. If I click the Resize button in the upper right hand corner, the window draws correctly. Other than that, it doesn't work correctly. Not sure if I'm explaining this well enough for someone to understand what the hell I'm talking about. I hope I have and I hope someone will have some information for me.
|
|
|
|
|
In your OnSize() method, are you calling the base class implementation? If not, yeah, things are gonna look pretty bad.
--------
Higher education helps your earning capacity. Ask any college professor. --Shog9 --
|
|
|
|
|
I know I can do -
CMenu* m_mMenu = AfxGetMainWnd()->GetMenu();
to get a pointer to the main menu, but how do I get a pointer to the specific menu in my FormView?
Ed
|
|
|
|
|
Replace the AfxGetMainWnd() with the handle of the FormView.
|
|
|
|
|
Thats what I figured, how do I get the handle of my FormView?
Ed
|
|
|
|
|
|
I am feeling like an idiot since I can't figure this out.
this->GetSafeHwnd() returns an HWND so do I cast it as CWnd?
I tried this:
CWnd* m_wwnd = (CWnd*)this->GetSafeHwnd();
CMenu* m_mMenu = m_wwnd->GetMenu();
it compiles but gives a memory fault.
Why is it so easy to get to the main window menu but not the menu attached to this child window???
Ed
|
|
|
|
|
ed9871 wrote:
I am feeling like an idiot since I can't figure this out.
I feel like this a lot when I ask questions here too, usually because my question is so basic and betrays my lack of knowledge in contrast to the professionals that hang about all day. But now that I see someone else mention it, I'm wondering, does it make any sense? Aren't we here to learn? I doubt there is such a thing as a dumb question.
- Jason
(SonorkID 100.611)
"I just recieved an email from myself but I didn't send it ?"
- Colin Davies, Sonork conference
|
|
|
|
|
Thanks Jason, it makes me feel better to know I'm not the only one who feels like this, especially after people have graciously answered my question and I still can't make it work. This seems like it should be easy, but I just can't seem to work it out.
Ed
|
|
|
|
|
ed9871 wrote:
CMenu* m_mMenu = AfxGetMainWnd()->GetMenu();
Now call GetSubMenu on the returned CMenu*
Nish
The posting stats are now in PDF:-
http://www.busterboy.org/codeproject/
Feel free to make your comments.
Updated - May 04th, Saturday
|
|
|
|
|
From your document you can also access your menu through:
CDocTemplate *pTemplate = GetDocTemplate() ;
pTemplate->m_hMenuShared ;
You can get the document from the view easily.
Don;y forget to call UpdateMenuBar() etc if you change the menu.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
Hi
anyone knows how to disable the CDROM or DVD autostart?
- Dominik
|
|
|
|
|
It's a setting under the Operating Systems / SysAdmin forum. Try there.
Jeremy L. Falcon
"You do not know the power of the dumb side."
<nobr>
Homepage : Sonork = 100.16311 Maybe my mangling might misguide malicious miscreants momentarily?
|
|
|
|
|
But i wanted to disable the autostart option programatically... i know how to disable the autostart using Windows's dialogs and the system control panel, but how to code this in C++?
|
|
|
|
|
Theres an article on MSDN about this, click
here (new window)
Dylan Kenneally
London, UK
|
|
|
|
|
Thanks!!!! That's perfect!
|
|
|
|
|
Hi there !
So this is from MSDN, so i think u should try it:
UINT g_uQueryCancelAutoPlay = 0;
BOOL DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
...
default:
if (!g_uQueryCancelAutoPlay)
{
g_uQueryCancelAutoPlay = RegisterWindowMessage(TEXT("QueryCancelAutoPlay"));
}
if (uMsg == g_uQueryCancelAutoPlay)
{
SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
return 1;
}
}
}
Hope this helps !
Olli
|
|
|
|
|
[ccode]
/*=============================================================================== Sorting a tree using CTreeCtrl::SortChildrenCB() =================================================================================*/CTreeCtrl *myTreeCtrl;static int CALLBACK MyCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort){ // lParamSort contains a pointer to the tree control.The lParam of an item is just its handle. CTreeCtrl *pmyTreeCtrl = (CTreeCtrl*) lParamSort; CString str2 = pmyTreeCtrl->GetItemText((HTREEITEM)lParam2); AfxMessageBox(str2); return 1;}//sorting treesvoid CSMPprojectDlg::SortTreeItem(){ HTREEITEM hRoot = m_TreeCtrl.GetRootItem(); HTREEITEM hNextItem = m_TreeCtrl.GetNextItem(hRoot,TVGN_NEXTVISIBLE); while( hNextItem != NULL ) { m_TreeCtrl.SetItemData(hNextItem,(DWORD)hNextItem); hNextItem = m_TreeCtrl.GetNextItem(hNextItem,TVGN_NEXTVISIBLE); } myTreeCtrl = &m_TreeCtrl; TVSORTCB tvs; tvs.hParent = m_TreeCtrl.GetRootItem(); tvs.lpfnCompare = MyCompareProc; tvs.lParam = (LPARAM)myTreeCtrl; m_TreeCtrl.SortChildrenCB(&tvs); MessageBox("hello");}void CSMPprojectDlg::SortingAtree(){ SortTreeItem();}
//but the messagebox in callback function print empty string... it is suppose to be print whatever i had set ( in my case file information, which are .type_size_date (.txt_231_5/3/02) )to
tv_instruct tree;tree.item.lParam = type_size_date;
[/ccode]
when inserting to tree.
i want to sort by date,by type, and by size like window explore
anyone have the same experience??
|
|
|
|
|
How are you setting items' data with SetItemData ? I suspect here lies the problem.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|