Network Programming

Core lib

  • sys/socket.h

It used for create socket, connect/listen/recv/send connection, send/recv data

// Main struct
struct sockaddr_storage;
struct sockaddr;

// Main Constance
AF_INET     // IPv4
AF_INET6    // IPv6
SOCK_STREAM // TCP
SOCK_DGRAM  // UDP

// Main functions
int socket(int domain, int type, int protocol);
int bind(int sockfd, const struct sockaddr * addr, socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int connect(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

ssize_t send(int sockfd, void *buf, ssize_t len, int flags);
ssize_t recv(int sockfd, void *buf, ssize_t len, int flags);


int shutdown(int sockfd, int how);
int getsockopt(...);
int setsockopt(...);
  • netinet/in.h

It used for define network address data structure and constancy.

// Main struct
struct sockaddr_in {
  sa_family_t sin_family; // AF_INET
  in_port_t sin_port; // port
  struct in_addr sin_addr // IP Address
}

struct in_addr {
  uint32_t s_addr; //IPv4 Address
}

// Main constancy
INADDR_ANY      // 0.0.0.0
INADDR_LOOPBACK // 127.0.0.1

// Example
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;
  • arpa/inet.h

It is a IP translate library, and main responsible for translate string ip to binary ip, and host byte to network byte.

// IP translation
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

uint16_t htons(uint16_t hostshort);
uint16_t ntohs(uint16_t netshort);
uint32_t htonl(uint32_t hostlong);
uint32_t htohl(uint32_t netlong);

// Example
inet_pton(AF_INET, "192.168.1.10", &addr.sin_addr);
  • unistd.h

A OS interface

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, void *buf, size_t count);

int close(int fd); // Most common function

pid_t fork(void);
int execve(...);
unsigned int sleep(unsigned int seconds);

Basic http server

#include <arpa/inet.h>
#include <iostream>
#include <netinet/in.h>
#include <string>
#include <sys/socket.h>
#include <unistd.h>

void createServer(int port) {
  int server_fd = socket(AF_INET, SOCK_STREAM, 0);

  if (server_fd < 0) {
    perror("socket error");
    return;
  }

  sockaddr_in addr{};
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(port);

  if (bind(server_fd, (sockaddr *)&addr, sizeof(addr)) < 0) {
    perror("bind error");
    return;
  }

  if (listen(server_fd, 10) < 0) {
    perror("listen error");
    return;
  }

  std::cout << "Server running at " << port << "\n";

  while (true) {
    int client_fd = accept(server_fd, nullptr, nullptr);
    if (client_fd < 0) {
      perror("accept error");
      continue;
    }

    char buffer[1024] = {0};
    ssize_t n = read(client_fd, buffer, sizeof(buffer) - 1);
    if (n < 0) {
      close(client_fd);
      perror("read error");
      continue;
    }

    std::string body = "Hello World";
    std::string res = std::string("HTTP/1.1 200 OK\r\n") +
                      "Content-Type: text/html\r\n" +
                      "Content-Length: " + std::to_string(body.length()) +
                      "\r\n" + "\r\n" + body;

    ssize_t len = write(client_fd, res.c_str(), res.size());

    if (len < 0) {
      perror("write error");
      continue;
    }

    close(client_fd);
  }

  close(server_fd);
}

int main() {
  createServer(8877);
}