• Chat program in c++
    13 replies, posted
I would like to make a simple multi-threaded chat program using sockets. It should be able to have more than one client connected. I tried searching on google for a tutorial with no luck. Do anyone know a good tutorial or tutorial page?
You don't need multiple threads for that, and it'll be simpler if you stick with one. On a POSIX system (e.g. Linux), take a look at the select() or poll() functions. On Windows, I believe the equivalent is WaitForMultipleObjects().
Using select() et al instead of threads also is much less of a resource hog, as far as I know.
[QUOTE=Wyzard;26999104]You don't need multiple threads for that, and it'll be simpler if you stick with one. On a POSIX system (e.g. Linux), take a look at the select() or poll() functions. On Windows, I believe the equivalent is WaitForMultipleObjects().[/QUOTE] select works fine on Windows too.
Or just [url]http://msdn.microsoft.com/en-us/library/ms738573%28v=vs.85%29.aspx[/url]
beejz guide to network programming was designed for linux, but works pretty much for windows too
[QUOTE=Icedshot;27002819]beejz guide to network programming was designed for linux, but works pretty much for windows too[/QUOTE] IIRC it has some notes on where Windows is different.
After reading this thread, I am curious. What are the pros and cons of using select() versus my current implementation: a multi-threaded, nonblocking socket per client throttled via sleep? [b]Edit:[/b] I remember the reason I didn't use select() in the first place now, but the question still remains. The reason is that I didn't want my threads to be blocking because terminating threads is "unsafe" according to the API; so, I thought it'd be better to use non-blocking methods. [url=http://msdn.microsoft.com/en-us/library/ms686717(v=vs.85).aspx][u]Source of my fears![/u][/url]
Your solution needs (1) the OS to handle a bunch of threads (2) spend some CPU resources to check the sockets, which possibly are not yet ready (3) could take a (probably negligible) while until the incoming data is read, whereas select() reacts immediately (4) locks for shared memory. Basically, select() only offers you benefits with no drawbacks, or at least I can't think of any.
select() will block indefinitely and my application is real-time. The only way to use select() in my application is to put it into a thread and TerminateThread() when I'm no longer networking. So, I have a new question: Is it safe to TerminateThread() on a thread blocking indefinitely via select()? [b]Edit:[/b] After reading the select() documentation a bit more, it seems you can call select() with a timeout of 0 to poll it. :sigh: That would get rid of my individual threads, but I'd still have to throttle it via sleep or set the timeout to 0.01. [b]Pros for switching to select()[/b] * 1 thread per all connections instead of 1 thread per connection * Less time to react to incoming data (negligible amount) * The CPU isn't checking to see if the sockets are ready (negligible) I'm not getting the mentioned shared lock optimization because the locks are already in place for other reasons. [b]Cons for switching to select()[/b] * I have to rewrite my implementation!
You can pass in a timeout-struct. And if you don't want to waste any time at all, but just check through each socket, do something else and repeat, then use a non-blocking recv(); if no data was available it'll return -1 and errno is EAGAIN.
Just make the sockets non-blocking using the previously mentioned [url=http://msdn.microsoft.com/en-us/library/ms738573%28v=vs.85%29.aspx]ioctlsocket[/url] function. That way you get the best of both worlds. Non-blocking sockets with no need for multiple threads and minimal amount of rewriting to be done (just copy your receive thread contents into a loop).
I found a tutorial that was good, but i have one problems. First off if i shutdown the client the server console gets flooded with the last message. Is it possible to type a message and receive one at the same time? Server main.cpp [code] int main() { bool done = false; char recMessage[STRLEN]; ServerSocket sockServer; sockServer.port = 5567; sockServer.PublicIP = "127.0.0.1"; sockServer.StartHosting(); while ( !done ) { sockServer.RecvData( recMessage, STRLEN ); cout<<recMessage<<endl; sockServer.BroadcastMessage(recMessage); } }[/code] Client main.cpp [code]int main() { bool done = false; char recMessage[STRLEN]; char sendMessage[STRLEN]; ClientSocket sockClient; sockClient.port = 5567; sockClient.PublicIP = "127.0.0.1"; cout<<"Connecting to " << sockClient.PublicIP << ":" << sockClient.port <<endl; sockClient.ConnectToServer(); //Connected while ( !done ) { sockClient.GetAndSendMessage(); sockClient.RecvData( recMessage, STRLEN ); cout<<"Recv > "<<recMessage<<endl; } sockClient.CloseConnection(); }[/code]
[QUOTE=WiZzArD;27004825]select() will block indefinitely and my application is real-time. The only way to use select() in my application is to put it into a thread and TerminateThread() when I'm no longer networking.[/QUOTE] What are the other stimuli that the application needs to respond to, besides activity on the sockets? If it's something time-based, you can use select()'s timeout parameter. If it's something like a condition variable, you may be able to tie it into the select() loop by writing a byte into a pipe after (or possibly instead of) signaling the condition. (And on Windows, I [i]think[/i] WaitForMultipleObjects() can actually include things like mutexes and condition variables in the set of things that it waits for.)
Sorry, you need to Log In to post a reply to this thread.