Advertisement

Thread Design

Started by January 20, 2006 02:15 PM
27 comments, last by hplus0603 19 years ago
Hello! First of all, I'm new in this forum and I'm not English, so there might be many mistakes. Please tell me then, so i can practise a little bit. I've got a question about the design of my threads, where I send and recv. I am programming a chat. On the server, every client has a thread and the clients have only one thread, where they send and recv. So that's my question: I always send and then recv. If someone wanna say, that there's nothing to do, he sends an 0 byte. If he has something to say, he send something non 0. So there is every time traffic, although the computers don't wanna say something. I think it might be a solution, if i create two sockets and for every connection 2 threads. One thread for send and one for recv. But is that the right solution? I hope you had understood my problem. mfg. (<- german word for "greetings" or something like this)
Quote:
. On the server, every client has a thread


That is almost never the right solution.

There are a couple of other threads on this board right now about how to use select() instead of threads, and how to use select() to be prepared to handle both user input, incoming chat data, and outgoing chat data. I suggest you look into them. In general, you will not need threads at all for a chat application.

Etwork is a small network messaging library that comes with a sample chat client and chat server (using Win32 GUI). You may get something out of studying that code (it's open source; MIT license).
enum Bool { True, False, FileNotFound };
Advertisement
Okay, thank you very much!

I have read a tutorial and now i have another question:
If I use select() on both sides, when does select() know, that i can send data, because on the other side, im waiting with recv until there is something sent. You understand what i wanna say?

mfg.
The networking infrastructure will buffer data until you ask for it. Thus, the sending side doesn't need to know whether the remote side is currently listening -- it can just send, and when the remote calls recv(), the data will get there.
enum Bool { True, False, FileNotFound };
Although threads aren't needed for situation, i think you should still experiment with threads. They are wierd creatures with the ability to expand simple programs into... 2 simple programs :) (or more). But seriously, threads aren't always the best way to go, but they can make your programming experience a bit more fun and flexible. Here is how a thread would be created..

Thread prototype:
Quote:
// Thead prototype to receive data
DWORD WINAPI RecvThreadProc(LPVOID lpParameter);


Thread implementation:
Quote:
DWORD WINAPI RecvThreadProc(LPVOID lpParameter)
{
while (1)
{
int bytesRecv;
char recvbuf[512];
bytesRecv = recv( m_socket, recvbuf, 512, 0 );
if ( bytesRecv == -1 )
{
// The connection was closed. Deal with it,
// send the user a message box or whatever.
closesocket(m_socket);
break;
}

if (!bytesRecv == 0 ||
(bytesRecv == SOCKET_ERROR &&
WSAGetLastError()== WSAECONNRESET ))
{
recvbuf[strlen(recvbuf)] = '\0'; // Add the NULL terminator
// Do as you please with the message. Presumably
// sending it to the screen.
}
}
}


To execute the thread:
Quote:

HANDLE hThread;
DWORD dwThread;

hThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)
RecvThreadProc, 0, 0, &dwThread);
Hello?
You should not need to use threads for a simple chat server, and even if you do decide to use them, a thread per client is a waste of resources and adds complexity that is not useful.

Also, be aware that threads are handled in different ways under linux and windows. If you are targetting both for your network system, you will need to either use a third party library, or roll your own thread wrapper. This can be a fair amount of work to implement and test properly. Don't get into the habit of placing platform specific code in #defines in general code.


Winterdyne Solutions Ltd is recruiting - this thread for details!
Advertisement
Quote:
Quote:
On the server, every client has a thread


That is almost never the right solution.


Thanks for the tip. I've just started a mmorpg and I'm currently using a thread per client on the server. The threads are responsible only for filling the global command queue (global in nature, not scope). Why is it so bad to create threads per socket as opposed to non-blocking sockets in a single thread? It seems like it would be more expensive to keep polling every socket in one thread, especially when a lot of the time, many of the clients aren't sending anything.

I'm using Java at the moment. I've found it quite easy to put each client in its own thread and use a BufferedReader and PrintStream for input and output respectively (just using strings at the moment). I haven't got the command queing code yet, but I figure I'll just use a ConcurrentLinkedQueue and all will be good.

[Edited by - SteveTaylor on January 21, 2006 5:15:28 AM]
Creating a thread per client has a significant overhead. There's also a per-socket overhead - creating / releasing sockets is expensive.

If using TCP, a common solution is to use non-blocking sockets and poll them using select() from within a thread, and have a separate listening thread, with a single socket. Select will return the sockets that have pending data on them, from the entire set. It's very fast.




Winterdyne Solutions Ltd is recruiting - this thread for details!
Thanks for your answers!
I will practise a little bit with select().

Yes, you're right, it's important for me that i can use my source on every os. At the moment i'm working with boost::thread, but i will try to use select(). If I have more questions i will ask you.

mfg.
Ok - if you're doing cross platform stuff, be sure to check if there's any differences between the windows and linux socket functions - (I've not touched Java in over 10 years) in C/C++ there's the ioctl() (linux) and socketioctl() (windows) disparity, and some differences in #defined names for return values, and the error checking differs.

Edit: Sorry got confused as to who I was replying to. :-)
Winterdyne Solutions Ltd is recruiting - this thread for details!

This topic is closed to new replies.

Advertisement