浏览器与进程通信(web server填坑)

终于把开了很久的web server的坑填上了,当然,以后还会慢慢优化。 刚开始的时候网上很多给的建 …

2019年3月11日

终于把开了很久的web server的坑填上了,当然,以后还会慢慢优化。

刚开始的时候网上很多给的建议都是用的websocket或者python封装好的API,虽然确实简单了不少,但我还是更倾向于从底层开始造轮子。

先从最基础的开始记录吧,手工模拟一个应用层的http协议。

#define MAXLINE 4096
int main(int argc, char const *argv[])
{
  int listenfd;
  const int on = 1;
  struct sockaddr_in servaddr, cliaddr;
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(9876);
  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  listenfd = socket(AF_INET, SOCK_STREAM, 0);
  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  bind(listenfd, (sockaddr*)&servaddr, sizeof(servaddr));
  listen(listenfd, 5);
  //response body
  char content[MAXLINE], name[] = "qinxin", passwd[] = "123456";
  sprintf(content, "Welcome to vakling.com:%s and %s\r\n<p>", name, passwd);
  sprintf(content, "%sThanks for visiting!\r\n<p>", content);
  close(STDOUT_FILENO);
  socklen_t clilen = sizeof(cliaddr);
  int connfd = accept(listenfd, (sockaddr*)&cliaddr, &clilen);
  dup(connfd); //STDOUT_FILENO->connfd
  //response head
  printf("HTTP/1.1 200 OK\r\n");
  printf("Content-length: %ld\r\n", strlen(content));
  printf("Content-type: text/html\r\n\r\n");
  printf("%s", content);
  fflush(stdout);
  exit(0);
}

其实原理很简单,因为HTTP也是基于TCP协议的应用层协议,所以直接使用socket获取来自浏览器的连接,然后直接从连接套接字connfd里获取HTTP数据,给出相应报文即可。我这里没有读取数据而是直接返回了一个数据报,包括起始行、首部和主体部分。

这样浏览器就可以通过IP+端口号的方式连接到我们的进程然后解析我们发出的数据报,最后显示把数据显示在浏览器上。

回馈结果如上,看起来很简单,实际上省略了web server最复杂的步骤——处理业务逻辑(Get,Post方法等),但是复杂归复杂,理解了原理以后就只是写代码调试的问题了,搭配上以前熟悉的epoll、多线程等框架处理高并发,写一个webserver其实并没有想象的那么困难。

共有 0 条评论