Ver1:最简单版本的WebServer

最简单版本的WebServer:

1.服务端初始化工作:

a).创建主动套接字:initList(port)

b).转为监听套接字:initList(port)

c).等候和接受连接:Accept(listenfd,&clientaddr,&sizeof(clientaddr));

2.处理客户端的请求:

a).解析请求行:解析方法,URL,版本;根据URL决定是页面属性

b).解析首部行

c).找到请求的资源

d).发送客户端请求资源

3.对IO的封装:

首先构造了一个结构体Servbuf

结构体中,fd与socket文件相绑定,cnt代表当前Servbuf结构体的缓存区中剩余的未读字节数,ptr指向目前未读的字节区域的第一个字节,buff为一个MAXBUFFER大小的缓冲区。

构造这个结构体是因为,如果频繁使用read来从socket文件中读取数据进入内存则要频繁切换内核,而如果直接将socket文件中的数据直接读取MAXBUFFER到Servbuf中,则只用read切换一次,以后往内存中读数据都只需要从Servbuf中通过memcpy即可,而不需要通过read来不断切换。

readServbuf(Servbuf* servbuf,void* usrbuf,size_t n):

这个函数用于从servbuf中读取n个字节到用户指定区域usrbuf。

首先while循环用于判断servbuf缓冲区中当前的数据量,如果小于等于0,说明上一次read的数据都已经转移到用户指定内存区域,需要再往Servbuf中"进一次货",这一次读取MAXBUFFER个数据,当然如果socket文件中剩余数据量不足MAXBUFFER则读取剩余数量。

“补货”完成后就是真正对Servbuf的读取

num取为要读取的数量,取为剩余字节数和n中的较小值。

memcpy对数据进行转移,同时操作cnt和ptr的更新。

int readServbufline(Servbuf* servbuf,void* usrbuf):

从Servbuf中读取一行数据,主要用于对HTTP包中的请求行和状态行进行读取。

思路很简单,buf为用户指向的区域,ptrack用于跟踪每次读取的一个字节是否为'\n',\n时跳出,说明一行读取完毕,返回n。

猜你喜欢

转载自www.cnblogs.com/lxy-xf/p/11117381.html