After creating the socket, you will have to indicate the port on which you will listen to connection requests and possibly specify the address if you do not want to listen to all the addresses of the machine. To do this, we will use the bind function by passing it 3 parameters:
We will therefore have to declare a variant of the sockaddr structure corresponding to AF_INET. This is the struct sockaddr_in type. We will start by zeroing the content of this structure via the bzero function of string.h, then we will assign, to the first field named here sin_family, the AF_INET value.
struct sockaddr_in adr_srv; bzero(&adr_srv, sizeof(adr_srv)); adr_srv.sin_family = AF_INET;
You must then fill in the sin_port field in the structure with the number of its TCP port on which the server is listening and possibly the sin_addr field with the address IPv4. (You can also leave the IPv4 address zero to listen on all interfaces.)
inet_aton("127.0.0.1", &adr_srv.sin_addr); adr_srv.sin_port = htons(80);
Having thus specified the address 127.0.0.1 and port 80, all that remains is to call the bind function so that the server is configured to listen to clients. We must then call the function listen which sets the queue of customers arriving simultaneously.
bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); listen(fd_srv, 5);
We must then wait, in a while loop, for the arrival of each connection from a client and obtain a connection socket to this client while we keep the server socket for receive the following customers.
To obtain a socket allowing dialogue with the client, we will use the accept function which requires 3 parameters:
int fd_con; struct sockaddr_in adr_cli; socklen_t adr_cli_len; adr_cli_len = sizeof(adr_cli); fd_con = accept(fd_srv, (struct sockaddr *) &adr_cli, &adr_cli_len);
We can then use the new socket to communicate with the client. And when the dialogue is finished, one of the protagonists of the communication must warn his counterpart of the closing of the socket via the function: shutdown then close the socket via the function: close from the unistd.h library. It is essential to do this on the server side in order to free up the space occupied, in the kernel, by the sockets opened for each client.
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <netdb.h> #include <sys/socket.h> #include <string.h> // for the function bzero #include <arpa/inet.h> // for the function inet_addr void server_dialog(int fd) { } int main() { int fd_srv, fd_con; struct sockaddr_in adr_srv, adr_cli; int err; socklen_t adr_cli_len; fd_srv = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd_srv < 0) { printf("Socket creation error!\n"); exit(1); } bzero(&adr_srv, sizeof(adr_srv)); adr_srv.sin_family = AF_INET; err = inet_aton("127.0.0.1", &adr_srv.sin_addr); if (err == 0) { printf("Invalid IPv4 address!\n"); exit(1); } adr_srv.sin_port = htons(8080); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Server port access error!\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Queue creation error!\n"); exit(1); } printf("Server launched!\n"); while(1) { adr_cli_len = sizeof(adr_cli); fd_con = accept(fd_srv, (struct sockaddr *) &adr_cli, &adr_cli_len); if (fd_con < 0) { printf("Error accepting incoming connection!\n"); exit(1); } printf("Connection accepted!\n"); server_dialog(fd_con); shutdown(fd_con, SHUT_RDWR); close(fd_con); printf("Client disconnected by server!\n"); } return 0; }
In languages like PHP or Python, there are libraries interfacing with system functions.
The example code written in C becomes in PHP:
function server_dialog($socket) { } $sock_srv = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($sock_srv== false) die("Socket creation error!\n"); $err = socket_bind($sock_srv, '127.0.0.1', 8080); if ($err == false) die("Server port access error!\n"); $err = socket_listen($sock_srv, 5); if ($err == false) die("Queue creation error!\n"); echo "Server launched!\n"; while (true) { $sock_con = socket_accept($sock_srv); if ($sock_con == false) die("Error accepting incoming connection!\n"); echo "Connection accepted!\n"; server_dialog($sock_con); socket_shutdown($sock_con); socket_close($sock_con); echo "Client disconnected by server!\n" }
The example code written in C becomes in Python:
import socket def server_dialog(sock) : ... try: sock_srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_srv.bind(('127.0.0.1', 8080)) sock_srv.listen(5) except socket.error: print("Server launch error!") exit() print("Server launched!") while True : try : (sock_con,adr_cli)=sock_srv.accept() print("Connection accepted!") server_dialog(sock_con) sock_con.shutdown() sock_con.close() print("Client disconnected by server!") except socket.error : print("Error accepting incoming connection!") exit()