文章目录
- [1 IPV4套接字结构体](#1 IPV4套接字结构体)
- [2 TCP客户端](#2 TCP客户端)
- [3 TCP服务器](#3 TCP服务器)
- [4 三次握手](#4 三次握手)
- [5 四次挥手](#5 四次挥手)
- [6 滑动窗口](#6 滑动窗口)
1 IPV4套接字结构体
2 TCP客户端
特点:出错重传 每次发送数据对方都会回ACK,可靠
tcp是打电话的模型,建立连接 使用连接 关闭连接
1.创建套接字api
函数
3 TCP服务器
比客户端多两个
bind 绑定端口号,
accpet 监听端口号
流程
1.创建套接字 socket
2.给套接字绑定端口和ip bind
3.进行监听 listen
将套接字由主动转换为被动
创建一个链接队列
4.提取链接 accept
从已完成链接队列提取链接
提取链接得到一个已连接的套接字,接下来用这个已连接的套接字和客户端通信
5.进行读写
6.关闭fd
函数
`
代码
cpp
#include<sys/socket.h>
#include<stdio.h>
#include<arpa/inet.h>
#include <unistd.h>
int main()
{
// 创建套接字
int lfd = socket(AF_INET, SOCK_STREAM, 0);
// 绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8000);
// addr.sin_addr.s_addr =INADDR_ANY; // 如果是0,绑定的是通配地址
inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr.s_addr);
bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
// 监听
listen(lfd, 128);
// 提取
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr*)&cliaddr,&len);
char ip[16]= "";
printf("new client ip = %s, port = %s", inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr,ip,16));
// 读写
char buf[1024] = "";
while(1)
{
int n = read(STDIN_FILENO, buf,sizeof(buf));
write(cfd, "hello",5);
read(cfd,buf,sizeof(buf));
printf("%s\n",buf);
}
// 关闭
close(lfd); // 关闭新连接
close(cfd); // 关闭已经连接的
return 0;
}
粘包
服务器向客户端发送 第一次发送512字节,当客户端还没读取完全时,又发送了1024个字节,则会发生粘包
4 三次握手
5 四次挥手
关闭,半关闭(只关闭应用层的收发,但底层还能收发)
mss 最大报文长度,一般出现在三次握手的前两次,用来告知对方发送数据的最大长度
MTU:最大传输单元 网卡
6 滑动窗口
窗口尺寸,缓冲区大小
红区有多大,还剩多少,
每一次读取数据后,回ack报文,报文中会携带当前缓冲区大小