zoukankan      html  css  js  c++  java
  • Linux 网络编程详解八

    TCP/IP协议三次握手机制
    TCP/IP是全双工通道,两端都可以读写,三次握手机制就是验证TCP/IP是否是全双工通道
    1.客户端调用connect()函数,阻塞客户端进程,客户端向服务器发送数据包SYN,包SYN的值是a,客户端状态置为SYN_SENT,表示向服务器发送验证
    2.服务器在调用listen()函数后,将socket套接字变成被动套接字,然后服务器端在accept()函数处阻塞(因为此时listen队列中没有已连接的文件描述符),
    此时服务器端状态是SYN_RCVD,表示等待客户端发送SYN包。当服务器接收到客户端的SYN的数据包之后(管道的一端可写),服务器端向客户端发送两个包SYN包和ACK包,
    SYN存放值b,ACK包中存放值a+1
    3.客户端接收到服务器的SYN包和ACK包(管道的另一端可写),校验ACK的值a+1
    判断服务器可以接收客户端发送的数据(管道的另一端可以读),既然服务器端可读可写,
    客户端状态置为ESABLISHED,表明客户端连接服务器成功,并且将服务器发送的SYN包的值b,加上1,生成ACK包发送给服务器,connect()返回
    4.服务器接收到客户端的ACK包,校验ACK包的值,确定客户端可以接收到服务器的数据(管道一端可读),
    说明管道两端都可读可写,服务器状态置为ESTABLISHED,accept()函数返回,服务器端和客户端连接成功。
    TCP/IP协议四次断开机制
    TCP/IP协议规定执行主动关闭那一端,进入TIME_WAIT状态。客户端,服务器都可以主动关闭连接
    1.假设客户端主动调用close()函数(进程退出也会调用close函数),客户端连接状态置为FIN_WAIT_1,向服务器发送两个数据包FIN(值为x)和ACK(值为y)
    2.服务器端TCP/IP协议接收到数据包FIN和ACK之后,服务器连接状态置为CLOSE_WAIT,服务器立刻向客户端发送数据包ACK(值为x+1
    注意:不是执行read()函数才能接收到数据包FIN和ACK,这两个数据包是TCP/IP协议内部接收的,并且接收之后将read()函数的返回值置0。
    3.客户端接收到ACK数据包,客户端状态置为FIN_WAIT_2
    4.服务器如果没有调用close()函数,服务器就会一直处于CLOSE_WAIT状态,调用close()函数后,
    服务器向客户端发送两个数据包FIN(值为y)和ACK(值为y+1),此时服务器连接的状态是LAST_ACK
    5.客户端接收到FIN数据包和ACK数据包,那么客户端就会置为TIME_WAIT状态
    TIME_WAIT可以存在一定的时间,原因是数据包(ACK y+1)发送失败了可以重新发送,这也是服务器有时候需要设置setsockopt()函数的原因
    6.服务器接收数据包(ACK y+1),将服务器端连接置为CLOSED状态
    为什么客户端关闭了服务器不会立刻处于CLOSED状态?
       客户端的读写虽然都关闭了,但是socket有缓存区,write()函数仍然可以向缓存区写数据,
    此时如果服务器端没有调用close()函数,服务器一直可以写,直到socket缓存数据被写满。所以服务器可以暂时处于CLOSE_WAIT状态。

     

    TCP/IP协议的第十一种状态
    当TCP/IP协议的两端同时调用close(),这时候两端将一同置为CLOSING状态,最后双方都进入TIME_WAIT状态

    注意:netstat -na | grep 8080命令下,TCP/IP的CLOSED状态不会显示出来。
  • 相关阅读:
    ubuntu下开发环境的搭建
    用移动存储设备安装Ubuntu全攻略
    LAMP服务器搭建
    PHP关闭提示、打印配置
    PHPmyadmin修改root密码
    转 sql2oracle
    SQL Server链接其他数据库服务器的方法(转)
    转(哈希查找)
    日语网址
    Reflector 右键注册
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/6142867.html
Copyright © 2011-2022 走看看