17. Sockets

Introduction

Writing a TCP Client

Writing a TCP Server

Communicating over TCP

Setting Up a UDP Client

Setting Up a UDP Server

Using UNIX Domain Sockets

Identifying the Other End of a Socket

Finding Your Own Name and Address

//------------------------------------------------------------------
#include <stdio.h>
#include <unistd.h> // gethostname()
#include <stdlib.h> // malloc(), realloc(), free()
#include <errno.h> // errno

...

char * hostname = NULL;
size_t sizebuf = 8;

hostname = malloc(size);
  

while( gethostname(hostname, sizebuf ) != 0 ) {
  if( errno != ENAMETOOLONG ) {
    perror("gethostname");
    exit(1);
  }
  // the buffer size is too small
  sizebuf += 8;
  hostname = realloc(hostname, sizebuf);
}
  
printf("my hostname : %s\n", hostname);

free(hostname);
  
...

//------------------------------------------------------------------
#include <stdio.h>
#include <sys/utsname.h> // struct utsname, uname()

...

struct utsname my_utsname;

uname( &my_utsname );

printf("my hostname : %s\n", my_utsname.nodename);

...

//------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

#include <netdb.h> // gethostbyname(), gethostbyaddr(), h_errno, herror()
#include <netinet/in.h> // struct in_addr
#include <arpa/inet.h> // inet_ntoa()

...

// we don't handle IPV6 for more simplicity
struct in_addr address;
struct in_addr * ip; 
struct hostent * host;
int i;

/*
    gethostbyname()
*/
char hostname[] = "a_valid_hostname";

if( (host = gethostbyname(hostname)) == NULL ) {
  herror("gethostbyname");
  exit(1);
}

for( i = 0; host->h_addr_list[i] != NULL; i++ ) {
  ip = ( struct in_addr *)(host->h_addr_list[i]);
  printf("address for %s : %s\n", hostname ,inet_ntoa(*ip));
} 

/*
    gethostbyaddr()
*/
char addr[] = "127.0.0.1";

// we verify the IPV4 address
if( inet_aton(addr, &address) == 0 ) {
  fprintf(stderr, "invalid address\n");
  return 1;
}

if( (host = gethostbyaddr( (char *)&address, sizeof(struct in_addr), AF_INET )) == NULL ) {
  herror("gethostbyaddr");
  exit(1);
}

printf("hostname for %s : %s\n", addr, host->h_name );
  
...

Closing a Socket After Forking

Writing Bidirectional Clients

Forking Servers

Pre-Forking Servers

Non-Forking Servers

Writing a Multi-Homed Server

Making a Daemon Server

Restarting a Server on Demand

Program: backsniff

Program: fwdport