计算机网络学习笔记10-HTTP协议
Posted studying~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络学习笔记10-HTTP协议相关的知识,希望对你有一定的参考价值。
HTTP协议:超文本传输协议,是基于TCP的应用层协议,它规定了浏览器和服务器通信的规则
特点:
1、支持C/S架构
2、简单快速:客户向服务器请求服务时,只需传送请求方法和路径 ,常用方法:GET、POST
3、无连接:每次连接只能处理一个请求
4、无状态:连接之间无论数据传输失败都不会重传
web服务器编写流程
若服务器本地磁盘无index.html则在调用open打开文件时会出错并通知浏览器
char err[]= "HTTP/1.1 404 Not Found\\r\\n" \\
"Content-Type: text/html\\r\\n" \\
"\\r\\n" \\
"<HTML><BODY>File not found</BODY></HTML>";
open打开成功则回应浏览器报文
char head[] = "HTTP/1.1 200 OK\\r\\n" \\
"Content-Type: text/html\\r\\n" \\
"\\r\\n";
参考代码(web服务器):
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
char head[] = "HTTP/1.1 200 OK\\r\\n" \\
"Content-Type: text/html\\r\\n" \\
"\\r\\n";
char err[]= "HTTP/1.1 404 Not Found\\r\\n" \\
"Content-Type: text/html\\r\\n" \\
"\\r\\n" \\
"<HTML><BODY>File not found</BODY></HTML>";
void *deal_client_fun(void *arg)//arg=new_fd
{
int new_fd = (int)arg;
//1、recv获取客户端的请求(只需要调用一次)
unsigned char buf[512]="";
recv(new_fd,buf,sizeof(buf), 0);
//2、解析buf 提取所请求的文件名
char file_name[128]="./html/";
sscanf(buf,"GET /%[^ ]", file_name+7);
if(file_name[7]=='\\0')
strcpy(file_name,"./html/index.html");
//3、打开本地文件
int fd = open(file_name, O_RDONLY);
if(fd < 0)//打开文件失败
{
perror("open");
//发送失败报文给客户端
send(new_fd, err, strlen(err), 0);
}
else//打开本地文件成功
{
//发送成功报文 请准备接受
send(new_fd, head, strlen(head), 0);
//不停的给浏览器客户端 发送文件数据
while(1)
{
//从本地文件读取数据
unsigned char buf[1024]="";
int ret = read(fd,buf,sizeof(buf));
printf("ret=%d\\n", ret);
if(ret<1024)//文件末尾 将数据发送出去
{
send(new_fd,buf,ret,0);
break;
}
send(new_fd,buf,ret,0);
}
//关闭本地文件描述符
close(fd);
}
close(new_fd);
return NULL;
}
//运行的方式:./a.out 8000
int main(int argc,char *argv[])
{
if(argc != 2)
{
printf("./a.out 8000\\n");
return 0;
}
//1、创建TCP监听套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket");
return 0;
}
//2、端口复用
int yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(yes));
//3、给服务器绑定固定的IP以及端口
struct sockaddr_in my_addr;
bzero(&my_addr,sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(atoi(argv[1]));
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(sockfd, (struct sockaddr *)&my_addr,sizeof(my_addr));
if(ret == -1)
{
perror("bind");
}
//4、使用listen函数 将套接字 由主动变被动 创建连接队列
listen(sockfd, 15);
//5、while不停的提取客户端 产生已连接套接字
while(1)
{
struct sockaddr_in cli_addr;
socklen_t cli_len = sizeof(cli_addr);
int new_fd = accept(sockfd,(struct sockaddr *)&cli_addr , &cli_len);
//遍历客户端的信息ip port
unsigned short port=ntohs(cli_addr.sin_port);
char ip[16]="";
inet_ntop(AF_INET,&cli_addr.sin_addr.s_addr, ip, 16);
printf("已有客户端:%s:%hu连接上了服务器\\n", ip, port);
//创建线程 服务于客户端
pthread_t tid;
pthread_create(&tid,NULL, deal_client_fun, (void *)new_fd);
pthread_detach(tid);
}
//关闭监听套接字
close(sockfd);
return 0;
}
运行结果:
以上是关于计算机网络学习笔记10-HTTP协议的主要内容,如果未能解决你的问题,请参考以下文章