一、TCP协议相关内容
(一)TCP头部标志
TCP头部包含多种标志位,各标志位功能明确,具体如下:
- SYN:作为请求连接的标志物,用于发起TCP连接请求。
- ACK:响应报文标志位,表明此报文为对之前收到的报文的响应。
- PSH:携带数据标志位,通知接收方应从缓冲区读取数据。
- FIN:请求断开连接标志位,用于主动请求终止TCP连接。
- RST:复位标志位(重置),当出现错误或连接异常时,用于重置连接。
- URG:紧急指针标志位,指示报文中存在需要优先处理的紧急数据。

同时,TCP首部结构包含20字节固定首部与长度可变的选项部分,固定首部涵盖源端口、目的端口、序号、确认号、窗口、偏移、检验和、紧急指针等字段,还包含上述标志位;选项部分长度可变,填充字段用于使首部长度符合要求。TCP报文段由TCP首部和TCP数据部分组成,在网络传输中,TCP报文段作为IP数据部分,加上IP首部后形成IP数据报进行传输。
(二)TCP核心机制
TCP协议通过一系列机制保障数据传输的安全可靠,并提升传输效率。
1. 确保数据安全可靠的机制
- 三次握手与四次挥手:三次握手用于建立可靠的TCP连接,第一次握手由客户端发送SYN报文请求连接,第二次握手服务器端回复SYN+ACK报文响应,第三次握手客户端发送ACK报文确认,连接建立;四次挥手用于断开TCP连接,客户端先发送FIN报文请求断开,服务器端回复ACK报文确认,待服务器端数据发送完毕后发送FIN报文,客户端再回复ACK报文,连接断开。
- 应答机制:TCP对每一包数据都会给出响应应答。发送数据时,序列号表示该包数据的起始编号;响应报文中的确认号是接收方收到的最后一个字节编号加1,以此确保数据有序接收。
- 超时重传机制:当数据发送出去后,若在指定时间内未收到接收方的响应,TCP会认为数据丢失,进而对该数据进行重传,保证数据不丢失。
- 滑动窗口机制:设置一段缓冲区,用于缓存TCP已发送但未收到响应、以及准备发送的数据,通过窗口的滑动来动态调整数据的发送节奏,提高数据传输的连续性和可靠性。
2. 提高传输效率的机制
- 延迟应答:发送数据的同时等待应答,避免频繁发送单独的应答报文,减少网络开销。
- 流量控制机制:结合TCP头部的窗口大小字段,接收方根据自身缓冲区的空闲情况,动态调整窗口大小并告知发送方,发送方据此调整发送速率,防止接收方因缓冲区溢出而丢失数据。
- 捎带应答机制:ACK报文(应答报文)可能与应用层的数据同时发送,将应答信息附着在数据报文中,减少单独发送应答报文的次数,提升网络资源利用率。
二、HTTP协议相关内容
HTTP(超文本传输协议)是万维网(WWW)体系中客户端与服务器之间通信的核心应用层协议,其相关内容围绕万维网数据标记、通信方式、数据展示及自身协议特性展开。
(一)万维网核心要素
- 数据标记 :万维网服务器后台通过URL(统一资源定位符)标记万维网数据,URL格式为
<协议>://<主机>:<端口><路径>
,可精准定位网络中的资源。 - 通信方式:万维网客户端与服务器之间使用HTTP协议进行通信,HTTP基于传输层的TCP协议,默认端口为80,备用端口为8080。
- 数据展示:万维网客户端通过HTML(超文本标记语言)展示请求到的数据,HTML能对文本、图片、链接等多种元素进行排版和描述,呈现丰富的网页内容。
(二)HTTP通信过程
HTTP通信需经历以下4个步骤,依赖TCP连接保障数据传输:
- 建立TCP连接:客户端向服务器发起TCP连接请求,通过三次握手建立可靠连接。
- 发送HTTP请求报文:TCP连接建立后,客户端向服务器发送HTTP请求报文,请求所需资源。
- 接收HTTP响应报文:服务器接收并处理请求后,向客户端发送HTTP响应报文,包含请求结果及相关数据。
- 断开TCP连接:客户端接收响应报文后,通过四次挥手断开与服务器的TCP连接。

(三)HTTP报文格式
HTTP报文分为请求报文和响应报文两类,均为面向文本的协议,报文字段由ASCII码串组成,字段长度不确定。

1. 请求报文
-
请求行 :包含方法、URL、版本,方法指定对资源的操作,常见方法及意义如下表所示:
方法(操作) 意义 OPTION 请求一些选项的信息 GET 请求读取由URL所标志的信息 HEAD 请求读取由URL所标志的信息的首部 POST 给服务器添加信息(例如,注释) PUT 在指明的URL下存储一个文档 DELETE 删除指明的URL所标志的资源 TRACE 用来进行环回测试的请求报文 CONNECT 用于代理服务器 -
首部行:由多个"首部字段名:值"组成,每个字段后接CRLF(回车换行),用于传递请求的附加信息,如客户端信息、请求内容类型等。
-
实体主体:通常不用,仅在部分请求(如POST)中用于携带向服务器提交的数据。
2. 响应报文
- 状态行 :包含版本、状态码、短语,状态码为三位数字,分为5大类共33种,不同类别代表不同响应状态:
- 1xx:通知信息,如请求收到或正在处理。
- 2xx:表示成功,如接受或知道请求。
- 3xx:表示重定向,需进一步行动完成请求。
- 4xx:表示客户差错,如请求语法错误或无法完成。
- 5xx:表示服务器差错,如服务器失效无法完成请求。
常见状态行示例: - HTTP/1.1 202 Accepted(接受)
- HTTP/1.1 400 Bad Request(错误的请求)
- HTTP/1.1 404 Not Found(找不到)
- 首部行:与请求报文的首部行格式类似,由"首部字段名:值"组成,传递响应的附加信息,如服务器信息、响应内容长度等。
- 实体主体:部分响应报文包含,用于携带服务器返回给客户端的数据,如网页的HTML内容、图片数据等。
代码训练
1、爬虫
cs
#include "head.h"
int create_tcp_connect()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket error");
close(sockfd);
return -1;
}
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(80);
seraddr.sin_addr.s_addr = inet_addr("117.34.49.212");
int ret = connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if(ret < 0)
{
perror("connect error");
return -1;
}
return sockfd;
}
int send_http_request(int sockfd)
{
const char *prqus = "GET / HTTP/1.1\r\n"
"Host: news.sohu.com\r\n"
"User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
"Accept-Language: en-US,en;q=0.5\r\n"
"Connection: close\r\n" // keep_alive close
"\r\n";
ssize_t cnt = send(sockfd, prqus, strlen(prqus), 0);
if(cnt < 0)
{
perror("send error");
return -1;
}
return 0;
}
int recv_http_response(int sockfd)
{
char buff[1024] = {0};
while(1)
{
ssize_t cnt = recv(sockfd, buff, sizeof(buff), 0);
if(cnt < 0)
{
perror("recv error");
return -1;
}
else if(cnt == 0)
{
printf("off\n");
break;
}
write(1, buff, cnt);
}
return 0;
}
int main(int argc, char const *argv[])
{
int sockfd = create_tcp_connect();
if(sockfd < 0)
{
return -1;
}
send_http_request(sockfd);
recv_http_response(sockfd);
close(sockfd);
return 0;
}