DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Scalable Support Request Analysis Using Embeddings, HDBSCAN, and Tiny LLMs
  • KV Cache Implementation Inside vLLM
  • When Retries Become a Denial-of-Wallet
  • The Bill You Didn't See Coming

Trending

  • Why Your AI Agent's Logs Aren't Earning Trust
  • Give Your AI Assistant Long-Term Memory With perag
  • Prompt Injection Is Real, So I Built a Python Firewall for LLM Pipelines
  • From "Vibe Coding" to Production: Setting Up an Evals Loop for Claude Agents

Parallel TCP/IP Socket Server With Multithreading and Multiprocessing in C

Learn how to use the C language to use a TCP/IP server to receive multiple client requests at the same time and run each client request in parallel.

By 
Abhijit Pritam Dutta user avatar
Abhijit Pritam Dutta
·
Updated Jun. 16, 20 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
259.2K Views

Join the DZone community and get the full member experience.

Join For Free

The primary intention of writing this article is to give you an overview of how we can entertain multiple client requests to a server in parallel. For example, you are going to create a TCP/IP server which can receive multiple client requests at the same time and entertain each client request in parallel so that no client will have to wait for server time. Normally, you will get lots of examples of TCP/IP servers and client examples online which are not capable of processing multiple client requests in parallel.  

In the first example, the TCP/IP server has been designed with multi-threading for parallel processing and in the second example, I have implemented the server with multi-processing to accomplish the same goal. 

Below is the server application (in C). Here I have created a function called socketThread, which is a thread function. Whenever a request comes to the server, the server’s main thread will create a thread and pass the client request to that thread with its ID. The thread will start processing with the client request, generate the report, and send it back to the client. As this is just an example, you need to put your own business logic in the thread function. I have just put a sleep statement here and am sending a hard-coded reply from the server to the client. This is just a very simple example and not a professional based TCP/IP server.  

The second program is a sample client to test this server. Both of these programs are for Unix/Linux environments only. 

socket_server.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include <arpa/inet.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include<pthread.h>

char client_message[2000];
char buffer[1024];
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void * socketThread(void *arg)
{
  int newSocket = *((int *)arg);
  recv(newSocket , client_message , 2000 , 0);

  // Send message to the client socket 
  pthread_mutex_lock(&lock);
  char *message = malloc(sizeof(client_message)+20);
  strcpy(message,"Hello Client : ");
  strcat(message,client_message);
  strcat(message,"\n");
  strcpy(buffer,message);
  free(message);
  pthread_mutex_unlock(&lock);
  sleep(1);
  send(newSocket,buffer,13,0);
  printf("Exit socketThread \n");
  close(newSocket);
  pthread_exit(NULL);
}

int main(){
  int serverSocket, newSocket;
  struct sockaddr_in serverAddr;
  struct sockaddr_storage serverStorage;
  socklen_t addr_size;

  //Create the socket. 
  serverSocket = socket(PF_INET, SOCK_STREAM, 0);

  // Configure settings of the server address struct
  // Address family = Internet 
  serverAddr.sin_family = AF_INET;

  //Set port number, using htons function to use proper byte order 
  serverAddr.sin_port = htons(7799);

  //Set IP address to localhost 
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");


  //Set all bits of the padding field to 0 
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

  //Bind the address struct to the socket 
  bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

  //Listen on the socket, with 40 max connection requests queued 
  if(listen(serverSocket,50)==0)
    printf("Listening\n");
  else
    printf("Error\n");
    pthread_t tid[60];
    int i = 0;
    while(1)
    {
        //Accept call creates a new socket for the incoming connection
        addr_size = sizeof serverStorage;
        newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);

        //for each client request creates a thread and assign the client request to it to process
       //so the main thread can entertain next request
        if( pthread_create(&tid[i++], NULL, socketThread, &newSocket) != 0 )
           printf("Failed to create thread\n");

        if( i >= 50)
        {
          i = 0;
          while(i < 50)
          {
            pthread_join(tid[i++],NULL);
          }
          i = 0;
        }
    }
  return 0;
}

This is an example of a simple multithreaded client for testing with 50 parallel requests to the server. If you want to test the client from a different machine, change the localhost to the actual server host and port number.

socket_client.c

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include<pthread.h>

void * cientThread(void *arg)
{
  printf("In thread\n");
  char message[1000];
  char buffer[1024];
  int clientSocket;
  struct sockaddr_in serverAddr;
  socklen_t addr_size;

  // Create the socket. 
  clientSocket = socket(PF_INET, SOCK_STREAM, 0);

  //Configure settings of the server address
 // Address family is Internet 
  serverAddr.sin_family = AF_INET;

  //Set port number, using htons function 
  serverAddr.sin_port = htons(7799);

 //Set IP address to localhost
  serverAddr.sin_addr.s_addr = inet_addr("localhost");
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

    //Connect the socket to the server using the address
    addr_size = sizeof serverAddr;
    connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
    strcpy(message,"Hello");

   if( send(clientSocket , message , strlen(message) , 0) < 0)
    {
            printf("Send failed\n");
    }

    //Read the message from the server into the buffer
    if(recv(clientSocket, buffer, 1024, 0) < 0)
    {
       printf("Receive failed\n");
    }
    //Print the received message
    printf("Data received: %s\n",buffer);
    close(clientSocket);
    pthread_exit(NULL);
}
int main(){
  int i = 0;
  pthread_t tid[51];
  while(i< 50)
  {
    if( pthread_create(&tid[i], NULL, cientThread, NULL) != 0 )
           printf("Failed to create thread\n");
    i++;
  }
  sleep(20);
  i = 0;
  while(i< 50)
  {
     pthread_join(tid[i++],NULL);
     printf("%d:\n",i);
  }
  return 0;
}

Compile both the client and the server in Linux or in Unix like below:

  •  cc socket_client.c -o client -lsocket -lnsl 

  • cc socket_server.c -o server -lsocket –lnsl  

First, run the server and then run the client from a different terminal (better to run both from different machines). When you run the client from a different Linux/Unix server, please consider the firewall issues. 

Now, below, is the server design with a multi-process approach for parallel processing. Here I am using the same function and calling it from a child process. In the previous example, the same process was called from a child thread. 

socket_server.c

C
x
95
 
1
#include<stdio.h>
2
#include<stdlib.h>
3
#include<sys/socket.h>
4
#include<netinet/in.h>
5
#include<string.h>
6
#include <arpa/inet.h>
7
#include <fcntl.h> // for open
8
#include <unistd.h> // for close
9
#include <sys/types.h>
10
11
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
12
13
void  socketThread(int  clientSocket)
14
{
15
  char client_message[2000];
16
  char buffer[1024];
17
18
  int newSocket = clientSocket;
19
20
  recv(newSocket , client_message , 2000 , 0);
21
22
  // Send message to the client socket
23
  pthread_mutex_lock(&lock);
24
  char *message = malloc(sizeof(client_message)+20);
25
  strcpy(message,"Hello Client : ");
26
  strcat(message,client_message);
27
  strcat(message,"\n");
28
  strcpy(buffer,message);
29
  free(message);
30
  pthread_mutex_unlock(&lock);
31
  sleep(1);
32
  send(newSocket,buffer,13,0);
33
  printf("Exit socketThread \n");
34
  close(newSocket);
35
  }
36
37
 
38
39
int main(){
40
  int serverSocket, newSocket;
41
  struct sockaddr_in serverAddr;
42
  struct sockaddr_storage serverStorage;
43
  socklen_t addr_size;
44
  pid_t pid[50];
45
  //Create the socket.
46
  serverSocket = socket(PF_INET, SOCK_STREAM, 0);
47
48
  // Configure settings of the server address struct
49
  // Address family = Internet
50
  serverAddr.sin_family = AF_INET;
51
52
  //Set port number, using htons function to use proper byte order
53
  serverAddr.sin_port = htons(7799);
54
 
55
  //Set IP address to localhost
56
  serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
57
58
  //Set all bits of the padding field to 0
59
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
60
61
  //Bind the address struct to the socket
62
  bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
63
64
  //Listen on the socket, with 40 max connection requests queued
65
  if(listen(serverSocket,50)==0)
66
    printf("Listening\n");
67
  else
68
    printf("Error\n");
69
    pthread_t tid[60];
70
    int i = 0;
71
while(1)
72
    {
73
        /*---- Accept call creates a new socket for the incoming connection ----*/
74
        addr_size = sizeof serverStorage;
75
        newSocket = (serverSocket, (struct sockaddr *) &serverStorage, &addr_size);
76
        int pid_c = 0;
77
78
      if ((pid_c = fork())==0)
79
        {
80
          socketThread(newSocket);
81
        }
82
        else
83
        {
84
          pid[i++] = pid_c;
85
          if( i >= 49)
86
           {
87
             i = 0;
88
             while(i < 50)
89
                waitpid(pid[i++], NULL, 0);
90
             i = 0;
91
           }
92
        }
93
    }
94
  return 0;
95
}


Requests

Opinions expressed by DZone contributors are their own.

Related

  • Scalable Support Request Analysis Using Embeddings, HDBSCAN, and Tiny LLMs
  • KV Cache Implementation Inside vLLM
  • When Retries Become a Denial-of-Wallet
  • The Bill You Didn't See Coming

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook