Skip to content

Instantly share code, notes, and snippets.

@chadnickbok
Created November 18, 2012 00:35
Show Gist options
  • Save chadnickbok/4101996 to your computer and use it in GitHub Desktop.
Save chadnickbok/4101996 to your computer and use it in GitHub Desktop.
Open a Linux Networking Socket
/**
* Simple TCP Server example.
*/
#include <iostream>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int net_listen(uint16_t port)
{
char port_str[8];
struct addrinfo hints;
struct addrinfo *result;
struct addrinfo *cur_ai;
int s;
int optval = 1;
int sfd = -1;
int backlog = 50;
// Convert port to string
sprintf(port_str, "%d", port);
port_str[5] = '\0';
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE; // Bind to all addresses
s = getaddrinfo(NULL, port_str, &hints, &result);
if (s != 0) {
fprintf(stderr, "ERROR: Cannot get address info for listen\n");
return 0;
}
for (cur_ai = result; cur_ai != NULL; cur_ai = cur_ai->ai_next) {
sfd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
if (sfd == -1) {
continue; // On error, try next address
}
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
close(sfd);
freeaddrinfo(result);
return -1;
}
if (bind(sfd, cur_ai->ai_addr, cur_ai->ai_addrlen) == 0) {
break; // Success
}
// Bind failed, close socket and try next address
close(sfd);
}
freeaddrinfo(result);
if (listen(sfd, backlog) == -1) {
return -1;
}
return (cur_ai == NULL) ? -1 : sfd;
}
int main() {
printf("Listening on 8080\n");
int cfd;
unsigned int addrlen;
struct sockaddr_storage claddr;
int sfd = net_listen(8080);
char addrstr[256];
char host[NI_MAXHOST];
char service[NI_MAXSERV];
const char *msg = "Hello, and goodbye\n";
signal(SIGPIPE, SIG_IGN); // Disable SIGPIPE for broken sockets
while(1) {
addrlen = sizeof(struct sockaddr_storage);
cfd = accept(sfd, (struct sockaddr *) &claddr, &addrlen);
if (cfd == -1) {
fprintf(stderr, "Could not accept client connection\n");
return 1;
}
if (getnameinfo((struct sockaddr *) &claddr, addrlen, host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {
printf("Connection from %s:%s\n", host, service);
} else {
printf("Connection from UNKNOWN\n");
}
write(cfd, msg, strlen(msg));
close(cfd);
}
printf("Done\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment