from (https://www.geeksforgeeks.org/socket-programming-cc/)
Server
// An highlighted block
// 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
int main(int argc, char const *argv[])
{
int server_fd, new_socket, 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
// output : return a integer( socket descriptor, like a file-handle) (if equals to zero -> failed)
// input : domain : AF_INET (IPv4 protocol) , AF_INET6 (IPv6 protocol), etc
// input : type : communication type
// SOCK_STREAM: TCP(reliable, connection oriented)
// SOCK_DGRAM: UDP(unreliable, connectionless)
// input : protocol: Protocol value for Internet Protocol(IP), which is 0.
// This is the same number which appears on protocol field
// in the IP header of a packet.(man protocols for more details)
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
// This helps in manipulating options for the socket referred by the file descriptor sockfd.
// This is completely optional, but it helps in reuse of address and port.
// Prevents error such as: “address already in use”.
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
// After creation of the socket, bind function binds the socket to the address and port number
// specified in addr(custom data structure). In the example code, we bind the server to the
// localhost, hence we use INADDR_ANY to specify the IP address.
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
// It puts the server socket in a passive mode, where it waits for the client to approach the
// server to make a connection. The backlog, defines the maximum length to which the queue of
// pending connections for sockfd may grow. If a connection request arrives when the queue is
// full, the client may receive an error with an indication of ECONNREFUSED.
if (listen(server_fd, 3) < 0)
{ // start to listening message, and maximum pending connections is three
perror("listen");
exit(EXIT_FAILURE);
}
// It extracts the first connection request on the queue of pending connections for the listening
// socket, sockfd, creates a new connected socket, and returns a new file descriptor referring to
// that socket. At this point, connection is established between client and server, and they are
// ready to transfer data.
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
// read the buffer message from the new established connection
valread = read( new_socket , buffer, 1024);
printf("%s\n", buffer );
// send message to the client
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
return 0;
}
Client
// 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};
// create socket, with the same type of the server
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;
}
// The connect() system call connects the socket referred to by the file descriptor
// sockfd to the address specified by addr. Server’s address and port is specified in addr.
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;
}