目录
http协议
Web服务器的实现
连接建立过程
http请求报头
http的应答状态
代码
http协议
浏览器与web服务器在应用层 通信使用的是HTTP协议(超文本传输协议),而HTTP协议在传输层使用的是TCP协议。那么浏览器需要和 web 服务器三次握手建立连接后,才可以发送HTTP请求报文,服务器收到请求报文后,向浏览器回复应答报文。
使用 HTTP 协议的程序一般默认使用 80 端口。
Web服务器的实现
连接建立过程
短连接:close 一次性
长连接:keep-alive 下一次请求时还可以继续使用。现在大部分web都使用长连接。
http请求报头
上图就是一个请求报文段的示例,重要的地方进行了标注。
http的应答状态
这里我们只简单的介绍几个,其他有兴趣的可以直接百度
| 200 OK | 请求成功 |
| 400 Bad Request | 通过客户请求错误 |
| 404 Forbidden | 资源没有找到 |
| 500 | 通用服务器错误 |
| 503 | 暂时无法访问服务器 |
代码
注:代码其中使用到的页面文件(.html)需要自己提供,并且和程序在同一位置
#include#include #include #include #include #include #include #include #include #define PATH "/home/wjy/桌面/tulun/day1217" int socket_init(); char * get_filename(char buff[]); int main() { int sockfd=socket_init(); assert(sockfd!=-1); while(1) { struct sockaddr_in caddr; int len =sizeof(caddr); int c =accept(sockfd,(struct sockaddr*)&caddr,&len); if(c<0) { continue; } char buff[512]={0}; int n=recv(c,buff,511,0); if(n<=0) { close(c); continue; } //获取请求文件名称 printf("read:n%sn",buff); char * filename=get_filename(buff); if(filename==NULL) { send(c,"404",3,0); close(c); continue; } printf("访问的资源名字:%sn",filename); //打开文件 char path[128]={PATH}; if(strcmp(filename,"/")==0) { strcat(path,"/index.html"); } else { strcat(path,filename); } int fd=open(path,O_RDONLY); if(fd==-1) { send(c,"404",3,0); close(c); continue; } //应答报文 int size=lseek(fd,0,SEEK_END); lseek(fd,0,SEEK_SET); char head[256]={0}; strcpy(head,"HTTP/1.0 200 OKrn"); strcat(head,"Sever:httpserrn"); printf(head+strlen(head),"Content_Length:%drn",size); strcat(head,"rn"); send(c,head,strlen(head),0); printf("head:n%sn",head); char data[1024]={0}; int num=0; while( (num=read(fd,data,1024))>0) { send(c,data,num,0); } close(c); } } char * get_filename(char buff[]) { char * s = strtok(buff,""); if (s=NULL) { return NULL; } printf("请求方法:%sn",s); s=strtok(NULL,""); return s; } int socket_init() { int sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1) { return -1; } struct sockaddr_in saddr; memset(&saddr,0,sizeof(saddr)); saddr.sin_family=AF_INET; saddr.sin_port=htons(80); //管理员运行 saddr.sin_addr.s_addr=inet_addr("127.0.0.1"); int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr)); if(res==-1) { return -1; } res=listen(sockfd,5); if(res==-1) { return -1; } return sockfd; }



