Threads in a client/server program
I don't know what language you're using but here are some basic ideas:
- Start your server in a thread (possibly your main thread).
- The server's while loop will block on accepting a socket connection.
- When the socket connection is accepted it should spawn a new thread to handle the connection.
- Start communicating with the client in the new thread.
A simple socket server loop looks like this (in Java):
while(true){ ClientWorker w; try{ //server.accept returns a client connection w = new ClientWorker(server.accept(), textArea); Thread t = new Thread(w); t.start(); } catch (IOException e) { // log the exception or something... } }
If you're wondering what it does- the ClientWorker
is available here. In C# if you're creating a new Thread
don't forget to set its IsBackground
property to true
so the thread closes when your app shuts down, i.e. no hanging threads.
Remember: accepting a socket connection or receiving data from a socket is usually a blocking call, which means that your thread will block until somebody connects to the socket or data comes through the socket.
In C#:
- The Chat Client: http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html
- The Chat Server: http://www.geekpedia.com/tutorial240_Csharp-Chat-Part-2---Building-the-Chat-Server.html
- A Basic Client/Server: http://www.dreamincode.net/forums/topic/33396-basic-clientserver-chat-application-in-c%23/
In Java:
- Chat Client/Server: http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html
- Nakov Chat Client/Server: http://inetjava.sourceforge.net/lectures/part1_sockets/InetJava-1.9-Chat-Client-Server-Example.html
In C++
- On Code Project: http://www.codeproject.com/KB/cpp/chat_client_server.aspx
- Another Code Project TCP/IP chat client/server: http://www.codeproject.com/KB/IP/ipchat.aspx
Update
Instead of doing global variables, just define a struct
for the client account and declare an account variable for each user... here is how you can define the account information:
struct account { char nickname[32]; char first_name[32]; char last_name[32]; char e_mail[32]; char password[32];};
When the client sends a message it should have a standard format: FROM|TO|CONTENT
struct message{ char nickname_from[32]; char nickname_to[32]; // optional char msg_content[256];};
Put each message
on the fifo [queue] and you will have all the information you need to identify who sent it.
Here is some psuedo code that might actually almost run. Note, I'm not freeing what I allocate, I'm not checking errors, I'm just trying to demonstrate how to pass a structure to a thread and use a simple mutex.
There is one thing to be careful of, The function pointer for threads specifies a void *
argument, which could be literally any kind of type. In the thread, we assume that its safe to cast the thread argument to a type that we've defined for use. If you are passing multiple possible types, you have to be careful :)
I'm not quite sure about the structure of your program, or how you are handling threads, but here's a short approach-agnostic example on how to pass data to them:
typedef struct client { char *firstname; char *lastname; char *email; char *nickname} client_t;pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER;void *client_thread(void *threadarg){ client_t *client = (client_t *) threadarg; pthread_mutex_lock(&client_lock); /* read and write to client structure */ pthread_mutex_unlock(&client_lock); /* do some other stuff */ pthread_exit(NULL);}int main(void){ client_t *client; pthread_t cthread; client = (client_t *)malloc(sizeof(struct client)); if (client == NULL) return 1; client->firstname = strdup("Joe Public"); /* set the rest of the data */ pthread_create(&cthread, NULL, (void *)client_thread, (void *)client); /* join / detach / etc */ /* Free all the structure members and the structure itself */ return 0;}
I'm pretty sure this is what you were asking?