TCP and UDP server using select

05 Nov, 2021
Prerequisites: TCP UDP
In previous articles, we have seen a TCP server and a UDP server. But now we can combine our concurrent TCP echo server and iterative UDP server into a single server that uses select to multiplex TCP and UDP socket.
The Select function is used to select between TCP and UDP sockets. This function gives instructions to the kernel to wait for any of the multiple events to occur and awakens the process only after one or more events occur or a specified time passes.
Example – kernel will return only when one of these conditions occurs
Any Descriptor from {1, 2, 3} is ready for reading
Any Descriptor from {4, 5, 6} is ready for writing
Time 5sec has passed
The entire process can be broken down into the following steps :
Server:
Create TCP i.e Listening socketCreate a UDP socketBind both sockets to the server address.Initialize a descriptor set for select and calculate a maximum of 2 descriptors for which we will waitCall select and get the ready descriptor(TCP or UDP)Handle new connection if the ready descriptor is of TCP OR receive datagram if the ready descriptor is of UDP
Create TCP i.e Listening socket
Create a UDP socket
Bind both sockets to the server address.
Initialize a descriptor set for select and calculate a maximum of 2 descriptors for which we will wait
Call select and get the ready descriptor(TCP or UDP)
Handle new connection if the ready descriptor is of TCP OR receive datagram if the ready descriptor is of UDP
UDP Client:
Create a UDP socket.Send a message to the server.Wait until a response from the server is received.Close socket descriptor and exit.
Create a UDP socket.
Send a message to the server.
Wait until a response from the server is received.
Close socket descriptor and exit.
TCP Client:
Create a TCP socket.Call connect to establish a connection with the server.When the connection is accepted write a message to a server.Read the response of the Server.Close socket descriptor and exit.
Create a TCP socket.
Call connect to establish a connection with the server.
When the connection is accepted write a message to a server.
Read the response of the Server.
Close socket descriptor and exit.
Necessary functions:
int select(int maxfd, fd_set *readsset, fd_set *writeset, 
fd_set *exceptset, const struct timeval *timeout);
Returns: positive count of descriptors ready, 0 on timeout, -1 error
Arguments:
maxfd: maximum number of descriptors ready.
timeout: How long to wait for select to return.
struct timeval{
long tv_sec;
long tv_usec;
};
if timeout==NULL then wait forever
if timeout == fixed_amount_time then wait until specified time
if timeout == 0 return immediately.
readset: Descriptor set that we want the kernel to test for reading.
writeset: Descriptor set that we want the kernel to test for writing.
exceptset: Descriptor set that we want the kernel to test for exception conditions.
int read(int sockfd, void * buff, size_t nbytes);
Returns:  number of bytes read from the descriptor. -1 on error
Arguments:
sockfd: Descriptor which receives data.buff: Application buffer socket descriptor data is copied to this buffer.nbytes: Number of bytes to be copied to application buffer.
sockfd: Descriptor which receives data.
buff: Application buffer socket descriptor data is copied to this buffer.
nbytes: Number of bytes to be copied to application buffer.
Server.c
C
// Server program#include <arpa/inet.h>#include <errno.h>#include <netinet/in.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <strings.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>#define PORT 5000#define MAXLINE 1024int max(int x, int y){    if (x > y)        return x;    else        return y;}int main(){    int listenfd, connfd, udpfd, nready, maxfdp1;    char buffer[MAXLINE];    pid_t childpid;    fd_set rset;    ssize_t n;    socklen_t len;    const int on = 1;    struct sockaddr_in cliaddr, servaddr;    char* message = "Hello Client";    void sig_chld(int);     /* create listening TCP socket */    listenfd = socket(AF_INET, SOCK_STREAM, 0);    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port = htons(PORT);     // binding server addr structure to listenfd    bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));    listen(listenfd, 10);     /* create UDP socket */    udpfd = socket(AF_INET, SOCK_DGRAM, 0);    // binding server addr structure to udp sockfd    bind(udpfd, (struct sockaddr*)&servaddr, sizeof(servaddr));     // clear the descriptor set    FD_ZERO(&rset);     // get maxfd    maxfdp1 = max(listenfd, udpfd) + 1;    for (;;) {         // set listenfd and udpfd in readset        FD_SET(listenfd, &rset);        FD_SET(udpfd, &rset);         // select the ready descriptor        nready = select(maxfdp1, &rset, NULL, NULL, NULL);         // if tcp socket is readable then handle        // it by accepting the connection        if (FD_ISSET(listenfd, &rset)) {            len = sizeof(cliaddr);            connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &len);            if ((childpid = fork()) == 0) {                close(listenfd);                bzero(buffer, sizeof(buffer));                printf("Message From TCP client: ");                read(connfd, buffer, sizeof(buffer));                puts(buffer);                write(connfd, (const char*)message, sizeof(buffer));                close(connfd);                exit(0);            }            close(connfd);        }        // if udp socket is readable receive the message.        if (FD_ISSET(udpfd, &rset)) {            len = sizeof(cliaddr);            bzero(buffer, sizeof(buffer));            printf("\nMessage from UDP client: ");            n = recvfrom(udpfd, buffer, sizeof(buffer), 0,                        (struct sockaddr*)&cliaddr, &len);            puts(buffer);            sendto(udpfd, (const char*)message, sizeof(buffer), 0,                (struct sockaddr*)&cliaddr, sizeof(cliaddr));        }    }}
TCP_Client.c
C
// TCP Client program#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#define PORT 5000#define MAXLINE 1024int main(){    int sockfd;    char buffer[MAXLINE];    char* message = "Hello Server";    struct sockaddr_in servaddr;     int n, len;    // Creating socket file descriptor    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {        printf("socket creation failed");        exit(0);    }     memset(&servaddr, 0, sizeof(servaddr));     // Filling server information    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(PORT);    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");     if (connect(sockfd, (struct sockaddr*)&servaddr,                            sizeof(servaddr)) < 0) {        printf("\n Error : Connect Failed \n");    }     memset(buffer, 0, sizeof(buffer));    strcpy(buffer, "Hello Server");    write(sockfd, buffer, sizeof(buffer));    printf("Message from server: ");    read(sockfd, buffer, sizeof(buffer));    puts(buffer);    close(sockfd);}
UDP_client.c
C
// UDP client program#include <arpa/inet.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <strings.h>#include <sys/socket.h>#include <sys/types.h>#define PORT 5000#define MAXLINE 1024int main(){    int sockfd;    char buffer[MAXLINE];    char* message = "Hello Server";    struct sockaddr_in servaddr;     int n, len;    // Creating socket file descriptor    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {        printf("socket creation failed");        exit(0);    }     memset(&servaddr, 0, sizeof(servaddr));     // Filling server information    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(PORT);    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    // send hello message to server    sendto(sockfd, (const char*)message, strlen(message),        0, (const struct sockaddr*)&servaddr,        sizeof(servaddr));     // receive server's response    printf("Message from server: ");    n = recvfrom(sockfd, (char*)buffer, MAXLINE,                0, (struct sockaddr*)&servaddr,                &len);    puts(buffer);    close(sockfd);    return 0;}
Steps to compile and run the above codes:
Compile the server program (gcc server.c -o ser)Run server using (./ser)On another terminal, compile tcp client program (gcc tcp_client.c -o tcpcli)Run tcp client (./tcpcli)On another terminal, compile udp client program (gcc udp_client.c -o udpcli)Run udp client (./udpcli)
Compile the server program (gcc server.c -o ser)
Run server using (./ser)
On another terminal, compile tcp client program (gcc tcp_client.c -o tcpcli)
Run tcp client (./tcpcli)
On another terminal, compile udp client program (gcc udp_client.c -o udpcli)
Run udp client (./udpcli)
Output of the above codes:
mohsenfayyaz77
sagartomar9927
saurabh1990aror
vaibhavsinghtanwar
Socket-programming
Computer Networks
Computer Networks
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
GSM in Wireless Communication
Secure Socket Layer (SSL)
Wireless Application Protocol
Mobile Internet Protocol (or Mobile IP)
Advanced Encryption Standard (AES)
Introduction of Mobile Ad hoc Network (MANET)
Intrusion Detection System (IDS)
Cryptography and its Types
Difference between URL and URI
Dynamic Host Configuration Protocol (DHCP)