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.