您现在的位置是:首页 >技术教程 >【网络编程】一文详解http协议(超文本传输协议)网站首页技术教程
【网络编程】一文详解http协议(超文本传输协议)
目录
五、http会话保持(客户端Cookie,服务器session)
一、http协议
1、http协议的介绍
http属于应用层协议。虽然应用层协议是程序员自己定的,但实际上, 已经有前辈们定义了一些现成的, 又非常好用的应用层协议, 供我们参考使用。 http(超文本传输协议) 就是其中之一,这个协议就是用户从服务器拿视频、图片等文件资源的一种协议。(这些资源存放在服务器的磁盘上)
2、URL的组成
平时我们俗称的 "网址" 其实就是说的 URL。
ip会标识一台网络主机,看到"/"就知道这台网络主机用的是Linux系统。使用url就可以通过浏览器请求这台网络主机的服务器,从指定的文件路径下找到用户请求的文件返回给用户。
3、urlencode和urldecode
像 / + : ?等字符, 已经被url特殊处理了。比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
转义的规则如下:取出字符的ASCII码,转成16进制,然后前面加上百分号即可。编码成%XY格式。服务器收到url请求,将会对%XY进行解码,该过程称为decode,如果哪天需要解码了,网上搜一下就行,这不是很重要的东西。
"+" 被转义成了 "%2B"。urldecode就是urlencode的逆过程。
二、http的请求方法、状态码及状态码描述、常见的响应报头
1、http请求方法
请求方法 | 说明 | 支持的http协议版本 |
GET | 获取资源 | 1.0/1.1 |
POST | 传输实体主体 | 1.0/1.1 |
其他方法不常用,略。 |
GET和POST方法提交参数的区别
客户端进行数据提交时,是通过前端的from表单提交的,浏览器会将from表单中的内容转换为GET/POST方法。
1、GET方法通过URL传递参数。例如http://ip:port/XXX/YY?key1=value1&key2=value2。像百度的搜索就是用的GET方法。GET方法通过url传递参数,参数注定不能太大,例如上传视频等巨长的二进制文件就不适合用GET了。
2、POST提交参数通过http请求正文提交参数。请求正文可以很大,可以提交视频等巨长的文件。
3、POST方法提交参数,用户是看不到的,私密性更高,而GET方法不私密。私密性不等于安全性,POST方法和GET方法其实都不安全!(http请求都是可以被抓到的,想要安全必须加密,使用https协议)
注意:如果用的是GET方法,需要对url进行额外的处理,例如/test.py?key1=value1&key2=value2,需要拆解出其中的路径(_path),即"test.py"。问号右侧则是参数(_parm)。
if(req._path=="test.py")
{
//建立进程间通信,pipe
//fork创建子进程,execl("/bin/python",test.py)进行进程程序替换
//父进程,将req._parm通过管道写给某些后端语言,例如py、java、php等
//....
return true;
}
2、http状态码及状态码描述
HTTP状态码是由服务器返回给客户端的三位数字代码,用于表示客户端请求的处理状态。以下是常见的HTTP状态码及其描述:
1xx(信息性状态码):表示请求已被接收,继续处理。
2xx(成功状态码):表示请求已成功被服务器接收、理解、并接受。
- 200 OK:请求成功。
- 201 Created:请求已经被实现,资源已经被创建。
- 204 No Content:请求成功,但响应报文不含实体的主体部分。
3xx(重定向状态码):客户端发送请求,服务器返回3XX状态码和一个新的URL,客户端拿着这个新的URL再次请求服务器,这就是重定向。
- 301 Moved Permanently:永久性重定向。
- 302 Found:临时性重定向。
- 304 Not Modified:客户端已经执行了GET,但文件未变化。
- 307 Temporary Redirect:临时性重定向。
4xx(客户端错误状态码):表示客户端请求出错,服务器无法处理请求。
- 400 Bad Request:请求报文存在语法错误。
- 401 Unauthorized:未经授权,需要身份验证。
- 403 Forbidden:服务器拒绝请求。
- 404 Not Found:服务器无法找到请求的资源。(属于客户端错误,客户端请求资源在服务器不存在)
5xx(服务器错误状态码):表示服务器处理请求出错。
- 500 Internal Server Error:服务器内部错误。
- 502 Bad Gateway:网关错误。
- 503 Service Unavailable:服务器暂时无法处理请求。
- 504 Gateway Timeout:网关超时。
以307状态码为例,临时重定向至CSDN首页:
std::string respLine="HTTP/1.1 307 Temporary Redirect
";//重定向,配合"Location: "使用
//响应报头
std::string respHeader=suffdeixDesc(req._suffix);//将后缀转换为对应的响应报头
if(req._size>0)
{
respHeader+="Content-Length: ";
respHeader+=std::to_string(req._size);
respHeader+="
";
}
respHeader+="Location: https://www.csdn.net/
";
3、http常见的响应报头
HTTP协议常见的响应报头包括:
- Content-Type:指定响应体的MIME类型,例如text/html表示HTML文本,image/jpeg表示JPEG图片等。
- Content-Length:指定响应体的长度,单位为字节。
- Cache-Control:指定缓存控制策略,例如no-cache表示不缓存,max-age=3600表示缓存1小时等。
- Expires:指定响应过期时间,通常与Cache-Control一起使用。
- Last-Modified:指定资源的最后修改时间,用于协商缓存。
- ETag:指定资源的唯一标识符,用于协商缓存。
- Location:搭配3XX状态码使用,指定重定向的目标URL。
- Set-Cookie:指定响应中的Cookie信息。
- Server:指定服务器软件的名称和版本号。
- X-Powered-By:指定服务器使用的编程语言和框架。
三、http协议客户端和服务器的通信过程
以个人云服务器作服务器,浏览器作客户端,服务器打印客户端请求如图:
这个http请求可以看到请求的设备信息,如果在手机端浏览器搜索“微信下载”,浏览器将会返回手机版的微信下载网页,若在电脑浏览器搜索,将会返回电脑版的微信下载网页。
以个人云服务器作服务器,浏览器作客户端,服务器的响应格式:
Content-Type: text/html 用于指示所传输的数据是HTML格式的文本。注意响应报头位置不要打成test了,这些都是设定好的,如果输错了,浏览器请求服务器时,会变成下载html文件!同样的,图片的响应报头写错了,当客户端请求图片时,同样会变成下载逻辑。
1、如何保证请求和响应被应用层完整的读取了?
1、可以读取完整的一行
2、while循环读取行,将所有的请求行和请求报头全部读完,直到遇到空行
3、我们可以保证把请求行和请求报头读完,报头中有Content-Length:XXX(正文长度)
4、通过Content-Length所示的长度,读取对应长度的正文即可。
一个用户看到的网页结果,可能由多个资源组合而成,所以要获取一张完整的网页效果,浏览器会发起多次http请求。所以需要根据客户端的请求信息,在服务器设置好不同的状态行和响应报头。
2、请求和响应如何做到序列化和反序列化
1、http不用关注json等序列化和反序列化工具,直接发送即可。服务器解析客户端的请求,获取其中的信息填充至响应缓冲区。服务器通过响应报头的方式返回请求的参数,在响应正文中返回请求的资源。
2、对于正文部分,如果需要的话,可以设计自定义序列化与反序列化方案。
3、客户端和服务器通信的全过程
void HandlerHttp(int sock)
{
//1、读取完整的http请求
char buffer[4096];
HttpRequest req;
HttpResponse resp;
size_t n=recv(sock,buffer,sizeof(buffer)-1,0);//读取套接字中的内容
if(n>0)
{
buffer[n]=0;//添加'