Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple echo server: Refactor #3: Change the work loop's while into a do { } while(), and make it smaller
/**
* Simple echo server
*
* This program listens for connections on the
* loopback interface, on port 9999. Upon connecting,
* The first line we read, of up to BUF_LEN bytes, is
* then sent back to the sender, and the connection
* is closed.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define BUF_LEN 25
static char buf[BUF_LEN + 1];
/**
* Read data from the given file descriptor,
* and echo it back out.
*/
static void handle_connection(int fd)
{
int i;
unsigned int bytes_read = 0;
/**
* Read data until the buffer is full, we get an EOF, or
* we've read a '\n'.
*/
do {
i = recv(fd, buf + bytes_read, BUF_LEN - bytes_read, 0);
if (i < 0) {
if (errno == EINTR)
continue;
perror("recv");
return;
}
bytes_read += i;
} while (bytes_read < BUF_LEN && i > 0 && !strchr(buf, '\n'));
/* Echo data if we got it */
if (bytes_read) {
buf[bytes_read + 1] = 0;
printf("Read: %s\n", buf);
if (send(fd, buf, bytes_read, 0) < 0)
perror("send");
}
}
int main(int argc, char *argv[])
{
int fd, c_fd, i=1;
struct sockaddr_in sa;
/* Open a TCP socket */
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket");
return EXIT_FAILURE;
}
/* Let's ensure we can reuse our address */
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(int));
/* This will bind to localhost:9999 */
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(9999);
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
perror("bind");
close(fd);
return EXIT_FAILURE;
}
/* Listen for one connection at a time */
if (listen(fd, 1) < 0) {
perror("listen");
close(fd);
return EXIT_FAILURE;
}
while (1) {
/* Clear the buffer */
memset(buf, 0, BUF_LEN+1);
if ((c_fd = accept(fd, NULL, NULL)) < 0) {
perror("accept");
break;
}
/* We've got a live one. */
printf("Got connection\n");
handle_connection(c_fd);
close(c_fd);
}
if (c_fd) close(c_fd);
close(fd);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment