Http之资源

1 概述

HTTP协议通过资源才能寻找到请求服务器位置,换句话说资源可以称为各种网络服务的资源地址。

2 URI

URI是通用的资源标示符,其包含URL和URN两个子集。其中URL是通过描述符的位置来标识资源的;URN是通过名字来标识资源的。

3 URL语法

基本语法格式如下

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
  1. : 访问服务器使用的协议,比如http代表HTTP协议。(必需)
  2. : 某些scheme访问时需要的用户名,默认为匿名。
  3. :用户名后面可能需要包含密码,用户名和密码中间用:分隔。
  4. :资源所在服务器的域名或者ip。所有用户名或密码则需要在host前加@。(必需)
  5. :资源所在服务器正在监听此服务的端口号,默认的HTTP端口号是80,HTTPS是443.
  6. :服务器上资源的本地路径,用/和之前部分区分开。(重要)
  7. :某些scheme可能需要这个组件来指定输入参数,参数为键值对。多个参数之间以;分隔,与前面的路径也是以;分隔
  8. :使用此参数传递参数以激活应用程序,用符号?跟之前的部分分隔开,查询组件之间用符号&分隔。
  9. :一小片或一部分资源的名字,引用对象时不会将frag字段传送给服务器;这个字段是在客户端内部使用的,通过符号#与其他部分Url分隔。

3.1 相对URL

相对URL时基于完整URL的缩写,其是基于基础URL,在基础URL上加上相对URL路径。其中基础URL可以通过以下途径获得:

  1. 首先,若资源中显式指定了基础URL,则直接使用。例如HTML中使用标记指定。否则
  2. 若当前资源存在URL,使用当前资源的URL作为基础URL。
  3. 否则,此URL为一个绝对URL,若不是则失败。

4 URL字符集

4.1 编码

编码机制就是通过一种“转义”表示法来表示不安全的字符。URL的转义有一个 % 后跟两个表示ASCII码的十六进制数表示。例如空格是%20

4.2 字符限制

一些特殊字符被保留起来,有着特殊含义,如下:

字符含义
%保留作为编码字符的转义标志
/保留作为路径组件中分隔路径段的定界符
.保留在路径组件中使用
..保留在路径组件中使用
#保留作为分段定界符
?保留作为查询字符串定界符
保留作为参数定界符
保留作为scheme、user/password, host/port定界符
$, +保留
@, &, =在某些scheme中有特殊含义
{}\^~[]’
<>”不安全,需要编码
0x00-0x1f,0x7f首先,ASCII码中不可打印区域
>0x7f受限,不在ASCII中

5 Scheme

常见的scheme说明如下:

  1. http 超文本传输协议,基本格式:http://<host>:<port>/<path>?<query>#<frag>
  2. https 使用了ssl加密机制的http协议,基本格式https://<host>:<port>/<path>?<query>#<frag>
  3. mailto 指向的是email地址,基本格式 mailto:xxx@xx.xx
  4. ftp 文件传输协议url,基本格式:ftp://<user>:<password>@<host>:<port>/<path>;<params>
  5. rtsp,rtspu 可以通过实时流传输协议解析音视频媒体的资源的标识符。后者表示是udp协议来获取资源。基本格式rtsp://<user>:<password>@<host>:<port>/<path>rtspu://<user>:<password>@<host>:<port>/<path>
  6. file 一台指定主机(本地或网络文件系统)上可以直接访问的文件。基本格式file://<host>/<path>
  7. news 位置无关的,不依赖于任何一个源服务器。也没有指定其源服务器地址,基本格式:news"<newsgroup>news:<news-article-id>
  8. telnet 用于访问交互式业务资源。基本格式:telnet://<user>:<password>@<host>:<port>/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如何在Linux C中获取HTTP资源: 1. 首先需要创建一个TCP socket连接,使用socket()函数创建一个套接字,然后调用connect()函数连接到HTTP服务器,指定服务器的IP地址和端口号。 2. 读取HTTP响应:发送HTTP请求后,使用read()或recv()函数读取HTTP响应。HTTP响应的构成通常包含响应状态码、响应头和响应体。我们需要解析响应头,获取Content-Type和Content-Length等信息。 3. 解析HTTP响应:通常会使用正则表达式或字符串截取来解析HTTP响应头。需要注意的是,HTTP响应的结构可以随时更改,因此应该编写健壮的代码以适应变化。 4. 下载资源:根据Content-Length和Content-Type的信息,可以推断出需要下载的资源大小和类型。使用read()或recv()函数从HTTP服务器读取响应体,并将数据写入磁盘文件中。 5. 关闭连接:需要使用close()函数关闭TCP socket连接。 编写模板: 一个典型的HTTP请求流程可以用以下伪代码描述: 1. 创建TCP socket连接,连接到HTTP服务器 2. 组织HTTP请求,发送HTTP请求 3. 读取HTTP响应头,解析响应头,获取资源类型和大小 4. 读取响应体,将响应体存储到本地文件中 5. 关闭TCP socket连接 具体实现将涉及到如何使用Linux C中的套接字和Socket API,如何解析HTTP响应头和响应体等。可以借助第三方库来简化任务,如curl和libcurl。 ### 回答2: 获取http资源是许多网络应用程序的基础功能之一。在Linux系统下使用C语言编写获取http资源的程序,可以通过以下步骤实现: 1. 引入头文件 #include <stdio.h> // 标准输入输出头文件 #include <stdlib.h> // 标准库头文件 #include <string.h> // 字符串操作头文件 #include <netdb.h> // 网络数据头文件 #include <sys/socket.h> // 套接字头文件 #include <netinet/in.h> // IPV4协议头文件 2. 创建套接字 int sockfd; struct sockaddr_in servaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); 3. 设置服务器信息 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); inet_pton(AF_INET, servip, &servaddr.sin_addr); 4. 连接服务器 connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); 5. 发送http请求 char *request = "GET / HTTP/1.1\r\nHost: www.showapi.com\r\n\r\n"; send(sockfd, request, strlen(request), 0); 6. 接受http响应 char buffer[1024]; memset(buffer, 0, sizeof(buffer)); recv(sockfd, buffer, sizeof(buffer), 0); 7. 处理响应数据 可以通过字符串函数处理响应数据,如strstr、strtok等函数。 8. 关闭套接字 close(sockfd); 以上是获取http资源的基本流程,在实际应用中可以根据需要进行拓展和优化。一些更高级的功能,如https访问、多线程、异步回调等,可以通过使用一些专业的网络库或框架来实现。 ### 回答3: 在 Linux 平台下使用 C 语言获取 HTTP 资源需要用到网络编程相关的知识和 API。以下是一个简单的获取 HTTP 资源的模板: 1. 包含相关头文件 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <sys/types.h> ``` 2. 定义连接服务器的函数 ```c int conn_server(char* hostname, char* port) { struct addrinfo hints, *res; int sockfd, status; // 使用 getaddrinfo 获取服务器 IP 地址和相关信息 memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(hostname, port, &hints, &res)) != 0) { perror("getaddrinfo error"); exit(1); } // 创建 socket 连接 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sockfd < 0) { perror("socket error"); exit(1); } // 使用 connect 函数连接服务器 if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) { perror("connect error"); exit(1); } freeaddrinfo(res); return sockfd; } ``` 3. 发送 HTTP 请求报文给服务器 ```c void send_request(int sockfd, char* hostname, char* path) { char msg[1024]; sprintf(msg, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", path, hostname); write(sockfd, msg, strlen(msg)); } ``` 4. 接收服务器响应并输出 ```c void recv_response(int sockfd) { char buffer[1024]; int count; // 不断从 socket 中读取数据,直到读完 while ((count = read(sockfd, buffer, sizeof(buffer))) > 0) { fwrite(buffer, sizeof(char), count, stdout); } } ``` 5. 主函数中调用以上三个函数 ```c int main(int argc, char *argv[]) { int sockfd; char *hostname, *path, *port; if (argc < 4) { fprintf(stderr, "Usage: %s <hostname> <port> <path>\n", argv[0]); exit(1); } hostname = argv[1]; port = argv[2]; path = argv[3]; sockfd = conn_server(hostname, port); send_request(sockfd, hostname, path); recv_response(sockfd); // 关闭 socket 连接 close(sockfd); return 0; } ``` 参考以上模板,可以编写出获取 HTTP 资源的基本程序。需要注意的是,在实际开发中还需要处理异常情况,比如连接超时、服务器返回错误码、接收数据过程中的中断等等。另外,如果要实现 HTTPS 请求,则需要使用 SSL 进行加密和认证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值