Looks like I am the first after you to post a sample. This example is in C. I was waiting for another one of these programming challenges.
Here is my code for simpleserver.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
void sigchld_handler(int s)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
}
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main()
{
FILE *fp;
int status, listenfd, commfd;
int yes = 1;
struct addrinfo hint, *res, *p;
struct sockaddr_storage their_addr;
struct sigaction sa;
socklen_t addr_size;
char message[128];
char s[INET6_ADDRSTRLEN];
fp = fopen("/tmp/socket.log", "a");
memset(&hint, 0, sizeof hint);
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
hint.ai_flags = AI_PASSIVE;
if ((status = getaddrinfo(NULL, "6789", &hint, &res)) != 0) {
fprintf(stderr, "getaddrinfo error %s\n", gai_strerror(status));
exit(1);
}
for (p = res; p != NULL; p = p->ai_next) {
if ((listenfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(listenfd, p->ai_addr, p->ai_addrlen) == -1) {
close(listenfd);
perror("server: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}
freeaddrinfo(res);
if (listen(listenfd, 20) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections...\n");
while (1) {
addr_size = sizeof their_addr;
commfd = accept(listenfd, (struct sockaddr *)&their_addr, &addr_size);
if (commfd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);
if (!fork()) {
close(listenfd);
if (recv(commfd, message, 128, 0) == -1) {
perror("recv");
}
else {
char *newline;
newline = strpbrk(message, "\n");
*newline = '\0';
char date[25];
time_t ourtime;
time(&ourtime);
struct tm *tmrecv = localtime(&ourtime);
strftime(date, 25, "%Y-%m-%d %I:%M:%S %p", tmrecv);
fprintf(fp, "%s ", date);
fprintf(fp, "from %s: %s\n", s, message);
}
close(commfd);
exit(0);
}
close(commfd);
}
fclose(fp);
return 0;
}
Most of the original code is from Beej's guide as this was the perfect excuse to go read up on sockets. Compiling is fairly simple just use clang or gcc.
Here is the log file after I ran it:
Code:
2013-04-26 11:54:50 AM from 127.0.0.1: hello there!
2013-04-26 11:55:07 AM from 127.0.0.1: This time we should have some output in the log rather than stdout.