三次握手与四次挥手在具体函数上的体现

简介: 三次握手与四次挥手在具体函数上的体现


网络编程 API组成

服务端API 客户端API
socket() socket()
bind() bind() [optional]
listen()
accept() connect()
recv()
send() send()
close() recv()
close()
shutdown()

三次握手服务器和客户端分别是发生在哪个函数

  • 服务器调用listen使服务器处于LISTEN状态,等待客户端请求连接
  • 首先客户端调用connect发起第一次SYN包,然后处于**SYN_SENT状态**,此时服务端会将这个连接放进半连接队列
  • 服务端收到SYN包以后会发送给客户端一个ACK|SYN包,此时服务端状态转移为SYN_RECV
  • 客户端接收到服务端发来的ACK|SYN包进行解析后会在半连接队列中查找携带这个信息的节点是否存在,如果存在则move出来加入全连接队列中,并且发送ACK包给服务端,此时客户端状态转移为ESTABLISHED
  • 服务端收到客户端的ack后也状态转移为ESTABLISHED

知识点:

半连接队列与全连接队列

  • 都是在服务端那里存在的队列

backlog参数的含义

  • 三种说法都存在
  • 半连接队列大小
  • 两个队列大小的和
  • 全连接队列大小
  • 本机上man listen查看
    defines the maximum length to which the pending connections for sockfd for sockfd may grow
    代表全连接队列的大小

ddos攻击

  • 客户端只发第一次握手,不会返回ACK,使半连接队列溢出

双方都发起第一次握手可以吗

  • 不可以,会导致连接无法正常建立

数据传输阶段

send返回整数不一定代表发送成功

  • send只是将数据拷贝到了内核,之后多久发送是协议栈规定的,自己不知道

为什么会发生发送不成功?

  • 据包在传输过程中很复杂,可能对方网络很差,在某一个路由器中丢包了,数据包总是根据目的ip、port来寻找

传输过程中的粘包分包问题

客户端调用sendsend只将数据拷贝到协议栈里面,其他什么都不做

如何做好分包粘包

  • 多次send会发生粘包和合包的问题
  • 解决
  • 应用层协议头前面加packetlen
  • 为每一个包加上分隔符 \r\n
  • 这两种做法有什么区别
// 先读长度,再读数据
read(tcphdr, 2);
read(tcphdr->length);
//or
while(count <tcphdr->length){
    size = read(tcphdr->lenghth - count);
    count += size;
}
// 检测内容
read(buffer, 1024);
buffer[idx] = "\r\n";
pkt = &buffer[idx + 2];  // 为了后续合包

网线断了立马重启,tcp是如何检测到的

  • 通过设计->心跳包来检测

网络断开连接

不分客户端或者服务器,只分主动或者被动

  • 首先调用close的端会将最后一次包的FIN位置为1,并且处于状态为FIN_WAIT1
  • 对端收到带有FIN的包后会返回给发送端一个ACK包,这个是立即发送的,代表我知道你不给我发数据了,之后对端状态转移为CLOSE_WAIT
  • 发送端接收到后状态转移为FIN_WAIT2
  • 之后对端在发送FIN包之前的这一段时间,它还可以给发送端发数据,当对端处理好所有数据后会发送最后的FIN包,此时状态会转移为LAST_ACK
  • 发送端接收到对端发送的FIN包之后会发送一个ACK包然后处于**TIME_WAIT状态**,过了这段时间后就处于**CLOSE状态**
  • 对端接收到ACK后连接断开,处于CLOSE状态

一些面试题:

  • 如果出现大量close_wait该怎么办(这种现象是因为recv返回0后到调用close时间太长)
  • 把业务数据释放与网路层的(recvclose)做一个分离,把他做成异步的,就是将释放资源客户端相关做成异步,这样一来recv==0后就可以立即close(fd)
  • 会出现双方同时调用close吗?引入closing
  • 以某一端为例,先发fin,进入fin_wait1,然后收到对端发送的fin包而不是ack,则为两端同时关闭,直接进入closing状态
  • 为什么会有time_wait
  • 如果laskack在传输过程中丢了,则对端会重发fin,如果没有time_wait则对应的端口会立即被释放出来,如果此时有一个应用程序连接进来刚好用到了该端口,则会直接收到fin包从而进入close_wait状态从而直接进入四次挥手
  • 为了避免最后一次ack丢失

简单总结各个函数的作用

socket

  • 文件系统分配fd,且分配一个tcb

bind

  • 绑定本地的ip、端口

listen

  • fd置为listen状态

accept

  • 从全连接队列中取出一个tcb(TCP control block)
  • 并分配一个fd

recv

  • 在对应的fd里面,将对应的readbuffer读出来

send

  • fd对应的tcb里面将数据拷贝到sendbuffer里面

close

  • sendbuffer里面的最后一个包的fin位置为1
  • 回收fd

客户端

bind

  • 可选,如果不调用则随机端口,调用则指定端口

connect

  • 准备一个syn包给服务端发送过去
  • 等待三次握手完成之后connect再返回
  • 思考:这个函数有没有等待的动作,是不是个阻塞的,如果连不上,会阻塞吗
  • 有等待的动作但不会阻塞,如果连不上则会被连接被拒绝
相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
负载均衡 安全 前端开发
深入理解微服务架构中的API网关
【7月更文挑战第4天】本文旨在探讨微服务架构中的关键组件——API网关,分析其作用、设计原则及实现方式。通过对比不同场景下的应用实例,揭示API网关在微服务生态系统中的重要性和实现细节。
143 2
|
XML Java 项目管理
pom
【7月更文挑战第21天】
207 3
|
监控 安全 数据安全/隐私保护
SNMPv3:网络管理的安全进化
【4月更文挑战第22天】
459 4
|
开发框架 前端开发 JavaScript
闲鱼技术2022年度白皮书-KUN主题-大终端领域的新物种-KUN(上)
闲鱼技术2022年度白皮书-KUN主题-大终端领域的新物种-KUN
674 0
闲鱼技术2022年度白皮书-KUN主题-大终端领域的新物种-KUN(上)
|
移动开发 人工智能 JSON
Python绘制的图形或者图像在vue的前端页面中显示
Python绘制的图形或者图像在vue的前端页面中显示的方法总结
1534 0
|
Java 调度 C++
jvm oop-klass对象模型
因此,当讲到jvm的对象模型的实现时候,可能会很自然地想到,只要java对象底层对应一个C++对象,问题就解决了。因为klassKlass的指针始终是指向自己的。其中_mark,_metadata一起合成为了对象头,里面包含了锁状态标志、线程持有的锁等标志,_metadata包含了两个指针,指向klass,klass包含了实例对象的元数据。上来就是三张图,c++写的,虽然咱们不能完全看明白,但是从定义属性这些大致也有了个了解,这个模型是由oop类和klass组合起来的,然后这两个大类下面又有很多的子类。
198 0
|
应用服务中间件 nginx 开发者
淘淘商城实现反向代理去掉端口号
淘淘商城实现反向代理去掉端口号
173 0
淘淘商城实现反向代理去掉端口号
|
Shell Linux 调度
关于Linux中作业调度 crond 和 systemd.timer 使用场景的一些笔记
写在前面 分享一些 systemd.timer 相关的笔记 博文内容涉及: systemd.timer 的一些介绍 cron VS systemd.timer 区别 如何创建 systemd.timer 作业调度 理解不足小伙伴帮忙指正
415 0
|
开发工具
软考中级(软件设计)----数据的进制转换以及算术逻辑运算
软考中级(软件设计)----数据的进制转换以及算术逻辑运算
326 0
软考中级(软件设计)----数据的进制转换以及算术逻辑运算
|
机器学习/深度学习 存储 人工智能
AI之NLP:自然语言处理技术简介(是什么/学什么/怎么用)、常用算法、经典案例之详细攻略(建议收藏)
AI之NLP:自然语言处理技术简介(是什么/学什么/怎么用)、常用算法、经典案例之详细攻略(建议收藏)

热门文章

最新文章