Threads in a client/server program Threads in a client/server program multithreading multithreading

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#:

  1. The Chat Client: http://www.geekpedia.com/tutorial239_Csharp-Chat-Part-1---Building-the-Chat-Client.html
  2. The Chat Server: http://www.geekpedia.com/tutorial240_Csharp-Chat-Part-2---Building-the-Chat-Server.html
  3. A Basic Client/Server: http://www.dreamincode.net/forums/topic/33396-basic-clientserver-chat-application-in-c%23/

In Java:

  1. Chat Client/Server: http://pirate.shu.edu/~wachsmut/Teaching/CSAS2214/Virtual/Lectures/chat-client-server.html
  2. Nakov Chat Client/Server: http://inetjava.sourceforge.net/lectures/part1_sockets/InetJava-1.9-Chat-Client-Server-Example.html

In C++

  1. On Code Project: http://www.codeproject.com/KB/cpp/chat_client_server.aspx
  2. 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?