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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Memory Management in Couchbase’s Query Service
  • How to Build Slack App for Audit Requests
  • Idempotency in Distributed Systems: When and Why It Matters
  • Perfecting CRUD Functionality in NextJS

Trending

  • Apache Doris vs Elasticsearch: An In-Depth Comparative Analysis
  • *You* Can Shape Trend Reports: Join DZone's Software Supply Chain Security Research
  • Scalable System Design: Core Concepts for Building Reliable Software
  • Scalable, Resilient Data Orchestration: The Power of Intelligent Systems

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
257.3K 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

  • Memory Management in Couchbase’s Query Service
  • How to Build Slack App for Audit Requests
  • Idempotency in Distributed Systems: When and Why It Matters
  • Perfecting CRUD Functionality in NextJS

Partner Resources

×

Comments
Oops! Something Went Wrong

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!