tiny http是一个500多行的简易http服务器,其中实现了http server最基本的操作,利于入门者学习socket编程和部分系统调用

系统数据结构 && 系统调用

  • Linux C API手册
  • stat结构体 解析1 解析2 解析3

    1. struct stat {
    2. dev_t st_dev; // 文件所在设备ID
    3. ino_t st_ino; // 结点(inode)编号
    4. mode_t st_mode; // 保护模式
    5. nlink_t st_nlink; // 硬链接个数
    6. uid_t st_uid; // 所有者用户ID
    7. gid_t st_gid; // 所有者组ID
    8. dev_t st_rdev; // 设备ID(如果是特殊文件)
    9. off_t st_size; // 总体尺寸,以字节为单位
    10. blksize_t st_blksize; // 文件系统 I/O 块大小
    11. blkcnt_t st_blocks; // 已分配 512B 块个数
    12. time_t st_atime; // 上次访问时间
    13. time_t st_mtime; // 上次更新时间
    14. time_t st_ctime; // 上次状态更改时间
    15. };
  • stat函数

文件系统相关,在tiny http中只是使用到用于判断文件的可执行情况

  1. #include <sys/stat.h>
  2. #include <unistd.h>
  3. struct stat st;
  4. char path[MAX_LEN];
  5. if(stat(path, &st) == -1)
  6. printf("获取失败");
  7. // 如果获取的是文件夹,就将index.html赋入
  8. if ((st.st_mode & S_IFMT) == S_IFDIR)
  9. strcat(path, "/index.html");
  10. if ((st.st_mode & S_IXUSR) || // 所有者可执行
  11. (st.st_mode & S_IXGRP) || // 所属组可执行
  12. (st.st_mode & S_IXOTH)) // 其他人可执行
  13. cgi = 1;
  • pipe函数 ```c 个人理解:
    1. IPC的一种,通过在内存中创建一个虚拟文件来完成通信??
    2. 需要声明一个数组,两个标识符,fds[0]读,fds[1]写。 int fds[2];
    3. FIFO如同一个队列,如果没有数据先被write,则read会被悬挂,直到有数据被写入

int pipe(int fds[2]);

Parameters : fd[0] will be the fd(file descriptor) for the read end of pipe. fd[1] will be the fd for the write end of pipe. Returns : 0 on Success. -1 on error. ```

dup2(oldfd, newfd),用户可以指定一个newfd数值,如果newfd数值已被程序使用,系统就会将newfd所指的关闭<关闭什么,应该是关闭fd2和之前文件表项之间的映射关系,然后再让fd2和fd指向同一个文件表项>,若newfd等于oldfd,则返回newfd,而不关闭newfd所指的文件。dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等.

关闭一个已经打开的文件

ssize_t read(int fd, void *buf, size_t count);
从文件描述符中读取给定字节到缓冲区。成功返回读取的字节数,出错返回-1并设置errno,如果在调read之前已到达文件末尾,则这次read返回0。

read & fread比较: fread就是通过read来实现的,fread是C语言的库,而read是系统调用 但是差别在read每次读的数据是调用者要求的大小,比如调用要求读取10个字节数据,read就会读10个字节数据到数组中,而fread不一样,为了加快读的速度,fread每次都会读比要求更多的数据,然后放到缓冲区中,这样下次再读数据只需要到缓冲区中去取就可以了。

ssize_t write(int fd, const void *buf, size_t count);
返回值:成功返回写入的字节数,出错返回-1并设置errno
写常规文件时,write的返回值通常等于请求写的字节数count,而向终端设备或网络写则不一定。
读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收到数据包,调用read从网络读就会阻塞,至于会阻塞多长时间也是不确定的,如果一直没有数据到达就一直阻塞在那里。同样,写常规文件是不会阻塞的,而向终端设备或网络写则不一定。

int putenv(const char* string);
函数说明:putenv()用来改变或增加环境变量的内容. 参数string 的格式为name=value, 如果该环境变量原先存在, 则变量内容会依参数string 改变, 否则此参数内容会成为新的环境变量.
返回值:执行成功则返回0, 有错误发生则返回-1.
错误代码:ENOMEM 内存不足, 无法配置新的环境变量空间.

int setsockopt(int socket, int level, int option_name,const void option_value, socklen_t option_len);
*

pid_t waitpid(pid_t pid, int *status, int options);

  • fork

  • execl

  • intptr_t 用来保证平台通用性。因为x64平台long为8 bytes,指针为8 bytes;x86平台long为4 bytes,指针为4 bytes。那又有什么用呢?????还不是要转换为相应的,那强转不是一样吗???

    • intptr_t做了宏定义,保证在两个当指针作为整数运算时,

      socket流程