• 第47天-简单的Web服务器(2013.09.23)


      1.练习 : 简单的Web服务器

     1 #ifndef _HEAD_H_
     2 #define _HEAD_H_
     3 
     4 #include <stdio.h>
     5 #include <string.h>
     6 #include <stdlib.h>
     7 #include <fcntl.h>
     8 #include <sys/socket.h>
     9 #include <arpa/inet.h>
    10 #include <unistd.h>
    11 
    12 #define MAX 1024
    13 #define MAX_LISTEN 10
    14 #define MAX_PATH 37
    15 #define MAX_NAME 18
    16 
    17 #define SER_IP "127.0.0.1"
    18 #define SER_PORT 8000
    19 #define ROOT "./www"
    20 
    21 #define REPLY_HEAD "HTTP/1.1 200 OK
    Content-Type:"
    22 #define TEXT "text/html"
    23 //#define IMG "image/html"
    24 #define IMG "jpg/html"
    25 #define REPLY_END "
    
    "
    26 
    27 void perror_exit(char *);
    28 
    29 #endif//_HEAD_H_
    heah.h
      1 //main.c
      2 #include "head.h"
      3 
      4 void perror_exit(char *str)
      5 {
      6     perror(str);
      7     exit(1);
      8 }
      9 
     10 int main(int argc, char *argv[])
     11 {
     12     int fd_socket = 0, opt = 1, err = 0, fd_ctl = 0, len = 0, fd_write;
     13     struct sockaddr_in serve_addr;
     14     char buf[MAX] = {0};
     15     char *start = NULL, *end = NULL, *type = NULL, *filename = NULL;
     16     char *asgv[2] = {0};
     17 
     18     fd_socket = socket(AF_INET, SOCK_STREAM, 0);
     19 
     20     bzero(&serve_addr, sizeof(serve_addr));
     21     serve_addr.sin_family = AF_INET;
     22     serve_addr.sin_port = htons(SER_PORT);
     23     inet_pton(AF_INET, SER_IP, &serve_addr.sin_addr.s_addr);
     24 
     25     err = setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
     26     if(-1 == err) {
     27         perror_exit("setsockopt");
     28     }
     29     err = bind(fd_socket, (struct sockaddr *)&serve_addr, sizeof(serve_addr));
     30     if(-1 == err) {
     31         perror_exit("bind");
     32     }
     33     err = listen(fd_socket, MAX_LISTEN);
     34     if(-1 == err) {
     35         perror_exit("listen");
     36     }
     37 
     38     while(1)
     39     {
     40         char path[MAX_PATH] = {0};
     41 
     42         bzero(buf, sizeof(buf));
     43         len = 0;
     44         //fd_ctl = accept(fd_socket, &serve_addr, sizeof(serve_addr));
     45         fd_ctl = accept(fd_socket, NULL, NULL);
     46         if(-1 == fd_ctl) {
     47             perror_exit("accept");
     48         }
     49         len = read(fd_ctl, buf, MAX);
     50         if(-1 == len) {
     51             perror_exit("read");
     52         }
     53         buf[len] = '';
     54         start = strstr(buf, " ");
     55         end = strstr(start + 1, " ");
     56         *end = '';
     57         filename = start + 2;
     58         printf("filename == %s
    ", filename);
     59         if(0 == strlen(filename)) {
     60             filename = "index.html";
     61         }
     62         printf("filename == %s
    ", filename);
     63         sprintf(path, "%s/%s", ROOT, filename);
     64         printf("path == %s
    ", path);
     65         err = access(path, X_OK);
     66         if(0 == err)
     67         {
     68             pid_t pid = 0;
     69             write(fd_ctl, REPLY_HEAD, strlen(REPLY_HEAD));
     70             write(fd_ctl, TEXT, strlen(TEXT));
     71             write(fd_ctl, REPLY_END, strlen(REPLY_END));
     72 
     73             pid = fork();
     74             if(-1 == pid) {
     75                 perror_exit("fork");
     76             }
     77             if(0 == pid) {
     78                 dup2(fd_ctl, STDOUT_FILENO);
     79                 asgv[0] = path;
     80                 asgv[1] = NULL;
     81                 execvp(asgv[0], asgv);
     82             }
     83             else {
     84                 close(fd_ctl);
     85                 wait(NULL);
     86             }
     87         }
     88         else {
     89             start = rindex(filename, '.');
     90             //if((! strcmp(start, "png")) || (! strcmp(start, "jpg"))) {
     91             if((! strcmp(start, "jpg"))) {
     92                 type = IMG;
     93             }
     94             else {
     95                 type = TEXT;
     96             }
     97 
     98             fd_write = open(path, O_RDONLY);
     99             if(fd_write != -1) {
    100                 write(fd_ctl, REPLY_HEAD, strlen(REPLY_HEAD));
    101                 write(fd_ctl, type, strlen(type));
    102                 write(fd_ctl, REPLY_END, strlen(REPLY_END));
    103 
    104                 while((len = read(fd_write, buf, MAX)))
    105                 {
    106                     write(fd_ctl, buf, len);
    107                 }
    108 
    109                 close(fd_write);
    110             }
    111         }
    112         close(fd_ctl);
    113     }
    114 
    115     return 0;
    116 }
    main.c

      2.首先运行编译好的文件

       打开浏览器 , 输入127.0.0.1:8000访问服务器

      3.UNIX Doamin Socket IPC

        优点 :更有效率 , 不需要经过网络协议栈,不需要打包拆包,计算效验和,维护序号和应答等,只需要将应用层数据从一个进程拷贝到另一个进程。

        原因 : IPC机制本质上是可靠的通讯 而网络通讯协议是为不可靠通讯设计的。

        扩展:面向流,数据报,消息时都是可靠的,即不会丢失也不会顺序错乱。

        是全双工的

        不同点 :UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示

      4,网络编程的地址是IP地址加端口号

        UNIX Doamin Socket IPC 的地址是一个socket类型的文件在文件系统的路径

      5.注意程序中的offsetof宏,它在stddef.h头文件中定义

        #define offsetof(TYPE, MEMBER)  ((int) & ((TYPE *) 0) -> MEMBER)

         作用 :测量结构里面成员的偏移量

        offsetof(struct sockaddr_un, sun_path)就是取sockaddr_un结构体的sun_path成员在结构体中的偏移,也就是从第几个字节开始是sun_path成员

      6.注意事项 :在回头http协议中每一行的末尾都是回车加换行

         HTTP头的第二行表示即将发送的文件的类型(称为)

          Text/html  

          纯文本文件是text/plain

          图片则是image/jpg, image/png 

        

  • 相关阅读:
    函数的调用-转载
    HTML常用标签-手打抄录-来自-烟雨飘零-拜谢
    CSS常用标签-手打抄录-感谢原未知博主-拜谢了
    JS函数表达的几种写法
    JS数组---转及补充--
    标准文档流特性-不含块级元素和行内元素
    块级元素和行内元素-标签收集-区别之处
    CSS盒子知识
    把应用push到/system/app上面后,出现java.lang.UnsatisfiedLinkError的问题
    Vysor:在电脑里控制你的安卓手机
  • 原文地址:https://www.cnblogs.com/cxw825873709/p/3335608.html
Copyright © 2020-2023  润新知