Created
November 18, 2012 00:35
-
-
Save chadnickbok/4101996 to your computer and use it in GitHub Desktop.
Open a Linux Networking Socket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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