nonocast / me

记录和分享技术的博客
http://nonocast.cn
MIT License
20 stars 0 forks source link

学习 C/C++ (Part 22: minimal web server) #293

Open nonocast opened 2 years ago

nonocast commented 2 years ago

创建 tcp server 框架

不到50行的净代码,

#include "flvhttpd.h"
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>

void error_die(const char *);
void accept_request(void *arg);

int main(void) {
  uint16_t port = 3000;
  struct sockaddr_in name = {.sin_family = AF_INET, .sin_port = htons(port), .sin_addr.s_addr = htonl(INADDR_ANY)};
  int on = 1;

  int httpd = socket(PF_INET, SOCK_STREAM, 0);
  if (httpd == -1) error_die("socket");
  if (setsockopt(httpd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
    error_die("setsocket failed");
  }
  if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) error_die("bind");
  if (listen(httpd, 5) < 0) error_die("listen");

  printf("server start at %d\n", port);

  int client = -1;
  struct sockaddr_in client_name;
  socklen_t client_name_len = sizeof(client_name);
  pthread_t newthread;

  while (true) {
    int client = accept(httpd, (struct sockaddr *)&client_name, &client_name_len);
    if (client == -1) error_die("accept");
    if (pthread_create(&newthread, NULL, (void *)accept_request, (void *)(intptr_t)client) != 0)
      perror("pthread_create");
  }

  close(httpd);

  return 0;
}

void error_die(const char *sc) {
  perror("error: ");
  exit(1);
}

void accept_request(void *arg) {
  printf("%s\n", __FUNCTION__);
  int client = (intptr_t)arg;
  char buffer[] = "HTTP/1.1 200 OK\nContent-type: text/html\nContent-length: 20\n\n<h1>hello world</h1>";
  write(client, buffer, strlen(buffer));
  close(client);
}

考虑Content-length:

char head[1024];
memset(head, 0x00, sizeof(head));
char head_format[] = "HTTP/1.1 200 OK\nContent-type: text/html\nContent-length: %d\n\n";
char body[] = "<h1>hello world, from httpd</h1>";
sprintf(head, head_format, strlen(body));
write(client, head, strlen(head));
write(client, body, strlen(body));
close(client);

参考文档