一步一步学做Web服务器(1)


 
  第1步:了解用到的结构体

  struct sockaddr_in {
 
  unsigned short sin_family; //AF_INET
  unsigned short sin_port;   //port
  struct in_addr sin_addr;  
  unsigned char sin_zero[8];
 
 
 
  } //#include <socket.h>
  这个结构体是网络套接字,在我们应用中,要把他转换成套接字sockaddr,其实内容都是一样的,但是c库使用的是sockaddr,所以我们也没办法
  struct sockaddr{
  unsigned short sa_family;
  char sa_data[14];
 
  }
  为了使用方便,我们做如下定义:
  typedef struct sockaddr SA;

  struct in_addr{
 
     unsigned int s_addr; //netwirk byte order

  } //#include <netinet/in.h>

  s_addr是32位无符号数,跟我们常说的IP地址是不同的,但可以互相转换,函数为inet_aton()(#include <arpa/inet.h>);
  转换完毕后,再用htonl()(#include <netinet/in.h>)函数把32位数转换成网络字节序(就是我们所说的大端)

  #define RIO_BUFSIZE 8192
  typedef struct{
 
  int rio_fd;
  int rio_cnt;
  char *rio_bufptr;
  char rio_buf[RIO_BUFSIZE];
  }rio_t
  这个结构体是RIO读写函数所用到的
 
  第二步: 主函数
 
int main(int argc, char **argv)
{
    int listenfd, connfd, port, clientlen;
    struct sockaddr_in clientaddr;

    /* Check command line args */
    //如果运行时,没有输入端口号作为参数,程序就给出提示后退出
    if (argc != 2) {
    fprintf(stderr, "usage: %s <port>/n", argv[0]);
    exit(1);
    }
    //把输入的端口号转成整形
    port = atoi(argv[1]);
    //Open_listenfd( )是自定义的函数,以后介绍,目的是侦听端口
    listenfd = Open_listenfd(port);
    //进入死循环
    while (1) {
        //计算结构体大小,即使你看出了结构体需要的字节数,也最好用这种方法,因为存在对齐,不同体系结构可能需要的空间不同
    clientlen = sizeof(clientaddr);
        //经过封装的Accept函数,没有连接时会阻塞
    connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
    //处理一个HTTP事务
    doit(connfd);
    //关闭连接
    Close(connfd);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章