一步一步學做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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章