Hello,
Is a WM_TIMER the only way to operate a Winsock connection and a window in a single thread? I like to practise working under restrictions (Asynchronous Winsock isn't permitted)
Hello,
Is a WM_TIMER the only way to operate a Winsock connection and a window in a single thread? I like to practise working under restrictions (Asynchronous Winsock isn't permitted)
I made a Socket class that has a "hasData()" function that uses select(). That way a server can loop through the client Socket's, only receiving if there's data to be had, and doesn't get tied up with any one client.
**Note: select() will let you know if a listening socket has clients waiting to connect, so you don't have to block for the accept()'s either.
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
Yeah, but I mean, in order to get it working properly in a single thread and keep a window's message loop going I'd have to use select(...) via a WM_TIMER of a short duration?
Not necessarily. This is my code:
Then, if sock is a listening socket, hasData() will return true if there is a client waiting to connect, or if it's a normal socket that sends/receives data, it will return true if data is waiting to be received.Code:bool hasData(SOCKET sock) { timeval t = {0,0}; fd_set fds; FD_ZERO(&fds); FD_SET(sock, &fds); return (::select(0, &fds, NULL, NULL, &t) > 0); }
Initializeing the timeval to {0,0} means that if there are no sockets with incoming connections/data, select() will return immediately, instead of waiting for a socket to have data.
This is probably not the best way of doing things, but it works and is pretty convenient a lot of the time.
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
I don't know about that... Maybe this is only a Windows thing, as you said, but straight from MSDN:The first argument of select() specifies the highest number of a socket descriptor that will be examined plus one
int select (
int nfds,
fd_set FAR * readfds,
fd_set FAR * writefds,
fd_set FAR * exceptfds,
const struct timeval FAR * timeout
);
Parameters
nfds
[in] This parameter is ignored; it is included only for
compatibility with Berkeley sockets.
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
Well, portability is out of the question for me anyways since I'm doing a Windows app, but I guess it would be good to learn the berkeleian way anyways, just in case I ever change an OS...
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
I think I need to put my question into context before I can get any useful answers...
I have a "download window", which has a static text control displaying information about the download and a progress bar showing how much has been downloaded. I must, in essence, simulataneously (Or as near as can be gotten) check for data to be received on an open socket as well as update the window. The window must also be able to deal with user events without being held up in any way, in a single thread.
Now, what you've told me is a method of checking whether a socket has any events waiting on it. What I was asking was how you could tie that in with allowing normal paint events, etc. to occur without any blockages. As far as I can see, I would:-
1. Start a WM_TIMER with a short duration (0.1 seconds or something), in the WM_CREATE event of the window.
2. In the WM_TIMER event, call select(...) on the socket to see if anything's there. If there is, get it and update the progress bar.
That way, the download would be handled in a fashion similar to any other event, which I think would not be good for performance. The only other way I could think of doing it would be to call select(...) inside the message loop (The GetMessage(...) - DispatchMessage(...) one), although any delay in the use of recv would hold up the loop completely, which is also not good.
Code:MSG msg; while(!done) { while(PeekMessage(...)) { (...) } if(hasData(theSocket)) { recv(theSocket, ...); updateProgressBar(); } }There would BE no delay with recv(), since recv() doesn't get called unless there's already data to be received.any delay in the use of recv would hold up the loop completely, which is also not good.
Just Google It. √
(\ /)
( . .)
c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.
I would suggest against using using select(..) on Windows. There are plenty of faster, and better alternatives. Check out OVERLAPPED completion routines or completion ports if you're looking for high performance/scalability.
This is pointless. Why can't you use asyncronous sockets? Using a timer is inefficient. If you set it to a short interval, you're eating CPU time. Plus, the timer interval creates a minimum time which clients must wait to be serviced.Originally posted by SMurf
Hello,
Is a WM_TIMER the only way to operate a Winsock connection and a window in a single thread? I like to practise working under restrictions (Asynchronous Winsock isn't permitted)
Ah, riiiiiiiight, I see. I kept thinking that what I was trying to do would cause some sort of blockage because IE gets regularly reduced to a window full of white while its status bar says "Done" when I load a page.
Perhaps it's a Microsoft quirk.
And I like to write code that's broadly compatible with other platforms, Ayebro. You can't get WSAAsync... anywhere else.
Last edited by SMurf; 07-02-2003 at 04:17 PM.