socket服务器如何读取http协议的一行

最近摸索着写了个简单的服务器,也阅读了一个小型webserver的源码,就是Tinyhttpd的源码。

发现,在从socket缓冲区读取一行方面,它的实现挺好玩,总结一下学习使用。


一般的话,从打开的fd中获得一行文本,调用的fgets();

例如:

int client;

FILE* pf = fdopen(client,"r");

char request[1024];

fgets(request,1024,pf);

他的实现是:

int get_line(int sock, char *buf, int size)
{
 int i = 0;
 char c = '\0';
 int n;
//读取直到换行,并且不管是'\r\n'结尾还是'\n'结尾,都统一成'\n'
 while ((i < size - 1) && (c != '\n'))
 {
  n = recv(sock, &c, 1, 0);//读取一个字符
  /* DEBUG printf("%02X\n", c); */
  if (n > 0)//读到了这个字符
  {
   if (c == '\r')//若是'\r'就继续读,因为可能是'\r''\n'换行的
   {
    n = recv(sock, &c, 1, MSG_PEEK);//<span style="line-height: 22.1000003814697px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">MSG_PEEK参数类似于预读取,本次读取的值仍在缓冲区仍可重复被读</span>
    /* DEBUG printf("%02X\n", c); */
    if ((n > 0) && (c == '\n'))//看看预读的数是否是'\n'
     recv(sock, &c, 1, 0);//如果是的话,就把'\n'彻底的从缓冲区中拿出来
    else
     c = '\n';<span style="white-space:pre">	</span>//如果下个数不是'\n',就把'\r'也替换成'\n'
   }
   buf[i] = c;
   i++;
  }
  else
   c = '\n';
 }
 buf[i] = '\0';//最后以'\0'结尾
 
 return(i);
}


具体解读过程已经在注释中。


你可能感兴趣的:(linux)