HTTP协议的应用
HTTP协议也称为超文本传输协议(Hypertext Transfer Protocol)是一个简单的基于请求-响应的协议,它通常运行在TCP之上,所以属于应用层协议。
浏览器基本都是基于该协议与服务器通信的,HTTP是基于 TCP/IP 协议来传输数据的,超文本的意思是指HTTP协议不只是支持普通数据,还支持传输文件、图片以及具有超链接功能。
HTTP请求头部

可以看到,整个 HTTP 请求头部由请求行、请求头部和请求包体组成,注意HTTP请求头部必须以”\r\n”回车换行符作为结束。
另外,请求行必须以 "\r\n" 结束,请求头部中的每个头部字段也需要使用 "\r\n" 进行分隔!
(1)请求行

(2)首部字段
HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。

客户端在发送请求消息的时候必须包含Host字段,该字段指定主机的域名,该字段格式如下:
客户端必须指定Host字段: Host : 主机域名 \r\n 比如 “Host: www.baidu.com\r\n”
HTTP请求方法
HTTP协议的请求方法常见的有 GET、HEAD、POST、PUT 等,每种请求方法的规则各不相同:

一般向服务器发起请求时需要指定服务器的URL,URL指的是统一资源定位符(英文全称是Uniform Resource Locator),用来表示所请求的资源在服务主机中的路径,格式如下:

HTTP协议版本
可以知道,HTTP协议的版本是由主版本号+次版本号组成的,最初的版本是HTTP/0.9,后期逐渐发展出其他版本,比如HTTP/1.0和目前最为主流的HTTP/1.1,但是还存在更高版本的HTTP协议。
HTTP协议的版本格式: HTTP + / + major + ‘.’ + minor 比如HTTP/1.0 HTTP/1.1 HTTP/2.0
练习:获取天气信息
点击查看代码
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
//http_socket客户端代码 ./xxx port IP
// https://api.seniverse.com/v3/weather/now.json?key=S88WsIa1zAQk_sxxf&location=shiyan&language=zh-Hans&unit=c
#define PORT 80
#define ADDR "116.62.81.138"
int main(int argc, char const *argv[])
{
//1.创建http_socket套接字
int http_socket = socket(AF_INET, SOCK_STREAM, 0);
if (http_socket == -1)
{
fprintf(stderr, "http socket error,errno:%d,%s\n",errno,strerror(errno));
exit(1);
}
//4.发起连接请求,等待接受服务器接受连接
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET; //协议族,是固定的
dest_addr.sin_port = htons(PORT); //服务器端口,必须转换为网络字节序
dest_addr.sin_addr.s_addr = inet_addr(ADDR); //服务器地址 "192.168.64.xxx"
int ret = connect(http_socket,(struct sockaddr *)&dest_addr,sizeof(dest_addr));
if (ret < 0)
{
fprintf(stderr, "connect error,errno:%d,%s\n",errno,strerror(errno));
exit(1);
}
char buf[1024] = {0};
//5.说明双方建立连接,此时可以利用http协议发送请求信息,并等待响应
//构造HTTP请求信息:请求行+请求字段+\r\n+请求包体(可选)
//请求行:GET URL HTTP/1.1\r\n
//请求字段:Host:api.seniverse.com\r\n
//\r\n
sprintf(buf,"GET https://api.seniverse.com/v3/weather/now.json?"
"key=S88WsIa1zAQk_sxxf&location=shiyan&language=zh-Hans&unit=c "
"HTTP/1.1"
"\r\n"
"Host:api.seniverse.com\r\n"
"\r\n"
);
send(http_socket,buf,strlen(buf),0);
//6.等待响应
char revbuf[1024] = {0};
recv(http_socket,revbuf,sizeof(revbuf),0);
recv(http_socket,revbuf,sizeof(revbuf),0);
printf("%s",revbuf);
bzero(revbuf,1024);
return 0;
}
浙公网安备 33010602011771号