【TCP】TCP通信
1. tcp三次握手
1.2 三次握手的过程
- tcp协议是面向连接的、安全的流式传输协议;
- 在数据传输前,必须保证通信双方建立起了连接;
- 握手是协议的行为,在connect()时进行,无需编程实现;
- 标志位含义
(1)SYN: 请求建立连接
(2)ACK: 同意
(3)FIN: 断开连接的请求
1.2 tcp协议中的序号
- 第一次握手:
(1)客户端将SYN置1,发出连接请求;
(2)客户端随机生成一个32bit的序号seq/Seq;
(3)这个序号后可以携带数据。 - 第二次握手:
(1)服务器同意请求ACK置1;
(2)服务器回发一个确认序号: ack/Ack=客户端随机序号+数据长度+SYN标志位;
(3)服务器发出连接请求:SYN置1;
(4)服务器会生成一个随机序号: seq=k; - 第三次握手:
(1)客户端同意请求ACK置1;
(2)客户端回发一个确认序号: ack/Ack=服务器随机序号+数据长度+SYN标志位;
2. 滑动窗口
- 滑动窗口是TCP中用于实现如 ACK 确认、流量控制、拥塞控制的承载结构。可以理解为一块缓存。
- 通信的双方都有滑动窗口;
(1)服务器:发送数据的窗口,接收数据的窗口;
(2)客户端:发送数据的窗口,接收数据的窗口; - 滑动窗口的内存是在变化的:其空间大小固定,但可存储的数据量在变化;其取决于通信对方可以接收的数据量。
- 使用流程
(1) mss: 最大的数据段大小 Maximum Segment Size -> 一条数据的最大数据量;
(2)win:滑动窗口。
1. 客户端向服务器发起连接, 客户端的滑动窗口大小为4096, 一次发送的最大数据量1460
2. 服务器接收连接请求(第二次握手), 告诉客户端服务器的滑动窗口大小为6144, 一次发送的最大数据量1024
3. 第三次握手
4. 4-9 客户端连续给服务器发送了 6k数据, 每次发送1k
5. 第10次, 服务器告诉客户端: 发送的6k数据已经收到存储到滑动窗口缓存中, 缓存数据已经处理了2k
6. 第11次, 服务器告诉客户端: 发送的6k数据已经收到存储到滑动窗口缓存中, 缓存数据已经处理了4k
7. 第12次, 客户端给服务器发送1k数据
3. 四次挥手
- 四次挥手发生在断开连接时,即调用
close()
函数时; - 客户端和服务器端谁都可以发起挥手的动作, 谁先调用close()函数就是谁发起的;
- 因为tcp在连接的时候, 建立的是双向连接, 因此在断开的时候需要双向断开;
1. 第13次, 主动请求和服务器断开连接, 并且给服务器发送了1k数据
2. 第14次, 服务器回复ACK8194, a: 同意断开连接的请求 b: 告诉客户端我已经收到刚才2k数据 c: 滑动窗口2k
3. 第15, 16次, 通知客户端滑动窗口中的数据处理完了
4. 第17次, 服务器给客户端发送FIN, 断开和客户端的连接
5. 第18次, 客户端同意了服务器的断开请求
4. TCP状态转换
4.1 三次握手
- 握手之前:服务器调用
listen()
函数设置监听,处于LISTEN
状态; - 第一次握手:客户端调用
connect()
函数发出连接请求,转为SYN_SENT
状态; - 第二次握手:
(1)服务器接受连接请求,转为SYN_RCVD
状态;并发出连接请求;
(2)客户端的请求被接受,转为ESTABLISHED
状态; - 第三次握手:服务器的请求被接受,转为
ESTABLISH
状态;
注意:双方必须都是ESTABLISHED状态才可以通信;
4.2 四次挥手
- 第一次挥手:
(1)发起方调用close()
函数请求断开连接,状态转为FIN_WAIT_1
;
(2)被动方状态转为CLOSE_WAIT; - 第二次挥手:发起方请求被同意,状态转为FIN_WAIT_2;
- 第三次挥手:
(1)被动方调用close()
函数发起断开连接请求,状态转为LAST_ACK;
(2)发起方状态转为TIME_WAIT; - 第四次挥手:发起方接受断开请求,被动方终止;
4.3 细节问题
- 2MSL(Maximum Segment Lifetime): 最大报文段寿命,官方建议2min,实际30s;发起方最后的TIME_WAIT会持续2MSL;
(1)第三次挥手后,发起方必须处于TIME_WAIT状态并储蓄2MSL时间;因为若第四次挥手的ACK丢失,可以在2MSL时间内重新发送。
(2)被动方若一直未收到第四次挥手的ACK信号,会一直发送第三次挥手的FIN,直到收到第四次挥手的ACK信号为止; - 半关闭:TCP连接中,A向B发送FIN请求关闭,B回应ACK后并未立即发送FIN给A,此时A处于半连接状态,A只能收不能发数据;
将sockfd文件设为how状态进行操作
#include <sys/socket.h>
int shutdown(int sockfd, int how);
- sockfd: 要操作的文件描述符
- how: 操作方式SHUT_RD: 关闭读SHUT_WR: 关闭写SHUT_RDWR: 关闭读写
- 端口复用
(1)正常情况下被动方断开连接后通信已经结束,发起方仍然会持续2MSL的TIME_WAIT状态。若发起方是服务器,立刻重启服务器则会失败,因为在此期间通信端口依然会占用。
(2)若程序突然退出而系统没有释放端口,也会导致该端口无法复用;
#include <sys/types.h>
#include <sys/socket.h>
// 设置套接字sockfd端口是否可以复用及复用的级别
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
参数:
- level: 级别:SOL_SOCKET (端口复用的级别)
- optname: 端口复用的级别(二选一)- SO_REUSEADDR- SO_REUSEPORT
- optval: 端口复用-> 对应的是整形数- 1: 可以复用- 0: 不能复用
- optlen: optval参数对应的内存大小
注意: 设置端口复用必须在端口绑定之前,即setsockopt()
在bind()
之前;
$ netstat
○ 参数:-a (all)显示所有选项,默认不显示LISTEN相关-p 显示建立相关链接的程序名-n 拒绝显示别名,能显示数字的全部转化成数字。-l 仅列出有在 Listen (监听) 的服务状态-t (tcp)仅显示tcp相关选项-u (udp)仅显示udp相关选项
【TCP】TCP通信相关推荐
- java tcp read_【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)...
书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子--反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 书上的服务器 ...
- 【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)(转)...
书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子--反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: 1 2 3 ...
- 《Linux高性能服务器编程》学习总结(四)——TCP/IP通信案例:访问Internet上的Web服务器...
第四章 TCP/IP通信案例:访问Internet上的Web服务器 HTTP协议是工作在应用层上的协议,其应用十分广泛,而在进行通信的过程中,经常使用HTTP代理服务器.HTTP代理服务器主 ...
- asp.core api 通过socket和服务器通信发送udp_【网络通信】TCP的通信过程
本文主要介绍以下几个内容: 1.TCP.UDP.Socket分别是什么?有什么区别? 2.TCP的基本过程. 3.TCP三次握手建立连接. 4.TCP四次挥手断开连接. 5.常考查其他问题. 1.TC ...
- TCP/IP通信程序设计方式
刚接触TCP/IP通信设计的人根据范例可以很快编出一个通信程序,据此一些人可能会认为TCP/IP编程很简单.其实不然,TCP/IP编程具有较为丰富的内容.其编程的丰富性主要体现在通信方式和报文格式的多 ...
- 高性能 TCP UDP 通信框架 HP-Socket v3.2.3
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#.Del ...
- 基于Java的TCP Socket通信详解(计算机端/Android手机端)
TCP Socket通信是一种比较常用的基于连接的网络通信方式.本文通过Java实现TCP Socket通信,并将其用于计算机端.Android手机端,同时做到代码规范化,实现代码最大化复用. 本文代 ...
- TCP/IP 通信示例
TCP/IP 通信示例 Global String ReadData_P_All$, ReadData_P$(10), data$ ' Global Preserve Double x Global ...
- EPSON TCP/IP 通信
EPSON SCARA机器人TCP/IP 通信时,涉及到的相关指令说明. 14.3 TCP/IP命令. OpenNet //打开TCP/IP端口. ChkNet //返回端口状态:等待读取的字节数或错 ...
- 网络通信之TCP Client通信(基于Arduino)
网络通信之TCP Client通信(基于Arduino) 前期准备 实验要求 具体方法 程序流程 程序 实验现象 后续 前期准备 Arduino IDE ESPDuino Arduino ESP826 ...
最新文章
- V7000存储运维使用手册
- MySQL(10)数据库实现高可用架构之MHA
- 【做题记录】图论杂题
- 没有写入hosts文件权限
- 太棒了!港大同济伯克利推出目标检测新范式:Sparse R-CNN
- 【NLP】毕设学习笔记(二)transformer
- ES6字符串的扩展方法~超详细哦
- Merkle Tree与区块链
- 关于DBC文件的格式解析(转)
- Qt中添加鼠标右键菜单
- 武汉理工大学-数值分析-2019年期末复习提纲
- Matlab实现snn代码,SNN系列|神经元模型篇(3)SRM
- 如何将“\”替换为任意字符
- openstack 使用iscsi连接网盘并提供cinder存储服务
- Java(JNI)Android使用JNI开发
- 打造Windows10堡垒主机(V1.0)
- win10计算机本地连接属性在哪里,Win10系统怎么打开本地连接属性
- 美的合肥荆州工厂均入选全球“灯塔工厂”;美国运通新版百夫长白金、黑金人民币卡将上市 | 美通企业日报...
- 设置系统引导,首启动项为windows
- HTTP协议响应状态码(301、302、303的区别)