Search code examples
csocketstcpserverclient

sockets programming: sending and receiving different data to different clients in C


I have written a basic client server code in c socket programming using the TCP/IP protocol but i cant figure out how to make it connect to different clients and send/receive different data to and from them as a function to the client (meaning if its the first client send him that data and if its that client send him the other data) and so on.

This is the only results i have found were sending the same data to different clients.

Current Server:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>

#include <netinet/in.h>

int main() {

  char server_message[100] = {0};
  int server_socket = 0;
  int client_socket = 0;

  struct sockaddr_in server_address;  

  server_socket = socket(AF_INET, SOCK_STREAM, 0);

  server_address.sin_family = AF_INET;
  server_address.sin_port = htons(9002);
  server_address.sin_addr.s_addr = INADDR_ANY;

  // bind the socket to our specified IP and port
  bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));

  listen(server_socket, 2);

  client_socket = accept(server_socket, NULL, NULL);

  printf("Please enter a massage:");
  fgets(server_message, 100, stdin);

  send(client_socket, server_message, sizeof(server_message), 0);

  close(server_socket);
  return 0;
}

Solution

  • By using original code from geeksforgeeks and Myst comment we can solve it.

    You have one server that serves on local host 127.0.0.1, and can have multiple clients for this example I assume 5 clients are enough.

    Run server once, and run many client to connect separately to that server.

    Server.c

    // Server side C/C++ program to demonstrate Socket programming 
    #include <unistd.h> 
    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <stdlib.h> 
    #include <netinet/in.h> 
    #include <string.h> 
    #define PORT 8080 
    #define STRING_SIZE 100
    #define BUFFER_SIZE 100
    
    int main(int argc, char const *argv[]) 
    {
         
        int server_fd, new_socket[5], valread; 
        struct sockaddr_in address; 
        int opt = 1; 
        int addrlen = sizeof(address); 
        char buffer[1024] = {0}; 
        
        char *hello = "Hello from server";
        
        // Creating socket file descriptor 
        if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) 
        { 
            perror("socket failed"); 
            exit(EXIT_FAILURE); 
        } 
        
        // Forcefully attaching socket to the port 8080 
        if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, 
                                                    &opt, sizeof(opt))) 
        { 
            perror("setsockopt"); 
            exit(EXIT_FAILURE); 
        } 
        address.sin_family = AF_INET; 
        address.sin_addr.s_addr = INADDR_ANY; 
        address.sin_port = htons( PORT ); 
        
        // Forcefully attaching socket to the port 8080 
        if (bind(server_fd, (struct sockaddr *)&address, 
                                    sizeof(address))<0) 
        { 
            perror("bind failed"); 
            exit(EXIT_FAILURE); 
        } 
        if (listen(server_fd, 3) < 0) 
        { 
            perror("listen"); 
            exit(EXIT_FAILURE); 
        }
         
        for (int i=0;i<5;i++){ 
            if ((new_socket[i] = accept(server_fd, (struct sockaddr *)&address, 
                            (socklen_t*)&addrlen))<0) 
            { 
                perror("accept"); 
                exit(EXIT_FAILURE); 
            } 
        valread = read(new_socket[i], buffer, 1024); 
        printf("%s\n", buffer);
        
        char send_buf[STRING_SIZE] = "hello";
        char buf[BUFFER_SIZE]={0};
        sprintf(buf, "%d", i);
        strcat(send_buf, buf);
    
        send(new_socket[i], send_buf, strlen(send_buf), 0); 
        //printf("Hello message sent\n"); 
        
        }
        
        return 0; 
    } 
    

    Client.c

    // Client side C/C++ program to demonstrate Socket programming 
    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <arpa/inet.h> 
    #include <unistd.h> 
    #include <string.h> 
    #define PORT 8080 
    
    int main(int argc, char const *argv[]) 
    { 
        int sock = 0, valread; 
        struct sockaddr_in serv_addr; 
        char *hello = "Hello from client"; 
        char buffer[1024] = {0}; 
        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
        { 
            printf("\n Socket creation error \n"); 
            return -1; 
        } 
    
        serv_addr.sin_family = AF_INET; 
        serv_addr.sin_port = htons(PORT); 
        
        // Convert IPv4 and IPv6 addresses from text to binary form 
        if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) 
        { 
            printf("\nInvalid address/ Address not supported \n"); 
            return -1; 
        } 
    
        if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
        { 
            printf("\nConnection Failed \n"); 
            return -1; 
        }
         
        send(sock , hello , strlen(hello) , 0 ); 
        //printf("Hello message sent\n"); 
        valread = read( sock , buffer, 1024); 
        printf("%s\n", buffer); 
        
        return 0; 
    } 
    

    Run

    Compile

    gcc client.c -o client
    gcc server.c -o server
    

    Open one terminal for server and start it by run ./server

    Now you can connect many client [up to 5] to it by running ./client

    Edit

    Thanks to anonymouse comment, Change server code with these lines.

    // Forcefully attaching socket to the port 8080                                                             
    int reuseaddr = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));                         
    int reuseport = setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));                         
    
    if (reuseaddr){                                                                                             
        perror("setsockopt addr");                                                                              
        exit(EXIT_FAILURE);                                                                                     
    }                                                                                                           
    if (reuseport){                                                                                             
        perror("setsockopt port");                                                                              
        exit(EXIT_FAILURE);                                                                                     
    }