Echo Server

How sockets are used for server processes differs slightly from how they are used in clients. The following sample program demonstrates how a simple echo server can be implemented:

#include<stdio.h> #include<netinet/in.h> #include<sys/types.h> #include<string.h>

char* echo_host = ""; int echo_port = 7777; int sockfd;

struct sockaddr_in *server=

(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));

/* Set own address */ server->sin_family = AF_INET;

server->sin_port = htons(echo_port); // Note network byte order!

server->sin_addr.s_addr = inet_addr(echo_host);

sockfd = socket(AF_INET, SOCK_STREAM, 0); /* Bind to an address */

if (bind(sockfd, (struct sockaddr*)server, sizeof(*server))) { printf("bind failed\n");

/* Enable server mode of socket */ listen(sockfd, SOMAXCONN);

struct sockaddr_in* client =

(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); int client_size = sizeof(*client); char* buf = (char*)malloc(1000); int bytes;

printf("Wait for connection to port %u\n", echo_port); /* Accept a connection request */

clientfd = accept(sockfd, (struct sockaddr*)client, &client_size); printf("Connected to %s:%u\n\n", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); printf("Numeric: %u\n", ntohl(client->sin_addr.s_addr));

while(1) { /* Endless loop */ /* Receive transmitted data */ bytes = read(clientfd, (void*)buf, 1000); if (bytes <= 0) { close(clientfd); printf("Connection closed.\n"); exit(0);

printf("Bytes received: %u\n", bytes); printf("Text: '%s'\nM, buf);

The first section is almost the same as the client code. An instance of the sockaddr_in structure is created to hold the Internet address of the server, but this is done for a different reason. The address of the server to which the client wishes to connect is specified in the client code. In this case, the address specified is that used by the server to wait for connections. The socket is generated in exactly the same way as for the client.

In contrast to the client, the server does not actively attempt to set up a connection to another program but simply waits passively until it receives a connection request. Three library functions (again based on the universal socketcall system call) are required to set up a passive connection:

□ bind binds the socket to an address ( in our example).6

□ listen instructs the socket to wait passively for an incoming connection request from a client. The function creates a wait queue on which all processes wishing to establish a connection are placed. The length of the queue is defined by the second parameter. (somaxconn specifies that the maximum system-internal number must be used so as not to arbitrarily restrict the maximum number of waiting processes.)

□ The accept function accepts the connection request of the first client on the wait queue. When the queue is empty, the function blocks until a client wishing to connect is available.

Again, actual communication is performed by read and write, which use the file descriptor returned by accept.

The client connection data (supplied by accept and consisting of the IP address and port number) are output for information purposes. While the client IP address for a specific computer is fixed, the port number is selected dynamically by the computer's kernel when the connection is established.

The function of the echo server is easily imitated by reading all client input with read and writing it back with write in an endless loop. When the client closes the connection, read returns a data stream that is 0 bytes long so that the server then also terminates.

Continue reading here: Client Server

Was this article helpful?

0 0