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