目录
前言
一、传输控制协议(TCP)
二、TCP报头字段详解
1、16位源端口与16位目的端口
2、4位首部长度
如何封装与解包?
我们又如何获取数据长度呢?
3、32位序号与32位确认序号
(1)确认应答机制
(2)序号引入
4、保留字段
5、六个控制位
6、窗口大小
7、校验和
8、紧急指针
9、选项
三、详解TCP可靠性
1、校验和
2、序号
3、确认应答机制
4、超时重传机制
5、去重机制
6、连接管理机制
(1)三次握手
(2)四次挥手
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
// 创建套接字
int listenSock = socket(AF_INET, SOCK_STREAM, 0);
if(listenSock < 0)
{
printf("create socket fail, errno:%d, errstr:%s\n", errno, strerror(errno));
exit(1);
}
// 绑定
struct sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr("0.0.0.0");
local.sin_port = htons(8888);
int n = bind(listenSock, (struct sockaddr*)&local, sizeof(local));
if(n < 0)
{
printf("bind sock fail, errno:%d, errstr:%s\n", errno, strerror(errno));
exit(2);
}
printf("bind socket success!\n");
// 监听
n = listen(listenSock, 32);
if(n < 0)
{
printf("listen sock fail, errno:%d, errstr:%s\n", errno, strerror(errno));
exit(3);
}
printf("listen socket success!\n");
// 死循环
int sockfd;
while (true)
{
struct sockaddr_in client;
memset(&client, 0, sizeof(client));
socklen_t len = sizeof(client);
sockfd = accept(listenSock, (struct sockaddr*)&client, &len);
}
return 0;
}
(3)理解TIME_WAIT状态
// 设置套接字可以重复绑定
int opt = 1;
setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
7、流量控制机制
(1)PSH控制位
(2)窗口探测与窗口更新通知
8、滑动窗口机制
补充: