1. 数据进入协议栈的封装过程

2. TCP连接的三次握手

3. TCP连接的三次握手和关闭时的四次握手

各个状态的意义如下: 
LISTEN - 侦听来自远方TCP端口的连接请求; 
SYN-SENT -在发送连接请求后等待匹配的连接请求; 
SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 
ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 - 从远程TCP等待连接中断请求; 
CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 
CLOSING -等待远程TCP对连接中断的确认; 
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 
TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 
CLOSED - 没有任何连接状态;

4. shutdown和close的区别

shutdown(SHUT_RD):在套接口上不能再发出接受请求;进程仍可往套接口发送数据;套接口接受缓冲区中所有数据被丢弃;再接收到的数据被TCP丢弃,对套接口发送缓冲区无影响.

shutdown(SHUT_WR)在套接口上不能在发出发送请求;进程仍可以从套接口接受数据;套接口发送缓冲区的内容被发送到对端,后跟正常的TCP连接终止序列(发送FIN);对套接口接收缓冲区无任何影响.

close(l_onoff=0缺省状态):在套接口上不能在发出发送或接收请求;套接口发送缓冲区中的内容被发送到对端.如果描述字引用计数变为0;在发送完发送缓冲区中的数据后,跟以正常的TCP连接终止序列(发送FIN);套接口接受缓冲区中内容被丢弃

close(l_onoff = 1, l_linger =0):在套接口上不能再发出发送或接受请求,如果描述子引用计数变为0,RST被发送到对端;连接的状态被置为CLOSED(没有TIME_WAIT状态),套接口发送缓冲区和套接口接受缓冲区的数据被丢弃

close(l_onoff =1, l_linger != 0):在套接口上不能在发出发送或接收请求;套接口发送缓冲区中的内容被发送到对端.如果描述字引用计数变为0;在发送完发送缓冲区中的数据后,跟以正常的TCP连接终止序列(发送FIN);套接口接受缓冲区中内容被丢弃;如果在连接变成CLOSED状态前延滞时间到,那么close返回EWOULDBLOCK错误.

  总结起来就是close关的时候一定是全关;shutdown可以实现半关闭,即只关闭读或者写。

  可参考 http://www.cnblogs.com/Jessy/p/3535612.html 将了内核中的整个执行流程。

5. 服务端如何判断连接已断开?

法一:
当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。
 
法二:
  struct tcp_info info; 
  int len=sizeof(info); 
  getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); 
  if((info.tcpi_state==TCP_ESTABLISHED))  则说明未断开  else 断开

法三:
若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。

法四:
int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测 
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误

法五:
自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。

参见: http://blog.csdn.net/hnlyyk/article/details/50819823?ref=myread

6. MTU和MSS

本文用到的抓包工具为wireshark,它的前身是赫赫有名的Ethereal。wireshark以太网帧的封包格式为:

----------------------------------------------------------------------------------------------------

Frame=Ethernet Header +IP Header +TCP Header +TCP Segment Data

----------------------------------------------------------------------------------------------------

(1)Ethernet Header =14 Byte =Dst Physical Address(6 Byte)+ Src Physical Address(6 Byte)+Type(2 Byte),以太网帧头以下称之为数据帧。

(2)IP Header =20 Byte(without options field),数据在IP层称为Datagram,分片称为Fragment

(3)TCP Header = 20 Byte(without options field),数据在TCP层称为Stream,分段称为Segment(UDP中称为Message)。

(4)54个字节后为TCP数据负载部分(Data Portion),即应用层用户数据。

Ethernet Header以下的IP数据报最大传输单位为MTU(Maximum Transmission Unit,Effect of short board),对于大多数使用以太网的局域网来说,MTU=1500。

TCP数据包每次能够传输的最大数据分段为MSS,为了达到最佳的传输效能,在建立TCP连接时双方将协商MSS值——双方提供的MSS值中的最小值为这次连接的最大MSS值。MSS往往基于MTU计算出来,通常MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460。

这样,数据经过本地TCP层分段后,交给本地IP层,在本地IP层就不需要分片了。但是在下一跳路由(Next Hop)的邻居路由器上可能发生IP分片!因为路由器的网卡的MTU可能小于需要转发的IP数据报的大小。这时候,在路由器上可能发生两种情况:

(1)如果源发送端设置了这个IP数据包可以分片(May FragmentDF=0),路由器将IP数据报分片后转发。

(2)如果源发送端设置了这个IP数据报不可以分片(Don’t FragmentDF=1),路由器将IP数据报丢弃,并发送ICMP分片错误消息给源发送端。

关于MTU的探测,参考《Path MTU discovery》。我们可以通过基于ICMP协议的ping命令来探测从本机出发到目标机器上路由上的MTU,详见下文。

TCP详解的更多相关文章

  1. 转载:tcp详解

    TCP详解 转自:http://www.cnblogs.com/kzloser/articles/2582957.html 首部格式 图释: 各个段位说明: 源端口和目的端口: 各占 2 字节.端口是 ...

  2. java网络编程(TCP详解)

    网络编程详解-TCP 一,TCP协议的特点              面向连接的协议(有发送端就一定要有接收端)    通过三次连接握手建立连接 通过四次握手断开连接 基于IO流传输数据 传输数据大小 ...

  3. 【TCP/IP】TCP详解笔记

    目录 前言 17. TCP 传输控制协议 17.1 引言 17.2 TCP 服务 17.3 TCP的首部 18. TCP连接的建立与终止 18.1 引言 18.2 连接的建立与终止 18.2.1 建立 ...

  4. 网络通信和TCP详解

    交换机.路由器.服务器组网 1. 通信过程(pc+switch+router+server) 较为复杂的通信过程如:访问 www.baidu.com 注意:一定要配置 PC:IP.NETMASK.DF ...

  5. Linux系统编程(31)—— socket编程之TCP详解

    TCP有源端口号和目的端口号,通讯的双方由IP地址和端口号标识.32位序号.32位确认序号.窗口大小稍后详细解释.4位首部长度和IP协议头类似,表示TCP协议头的长度,以4字节为单位,因此TCP协议头 ...

  6. TCP/IP笔记(七)TCP详解

    TCP的特点及其目的 为了通过数据包实现可靠性传输,需要考虑很多事情,例如数据的破坏.丢包.重复记忆分片顺序混乱等问题.如不能解决这些问题,也就无从谈起可靠传输. TCP通过检验和.序列号.确认应答. ...

  7. TCP 详解

    计算机网络中比较中要的无非就是 TCP/IP 协议栈,以及应用层的 HTTP 和 HTTPS . 前几天一直炒的的比较火的就是 HTTP/2.0 了,但是其实 HTTP/2.0 早在2015年的时候就 ...

  8. TCP详解——连接建立与断开

    一.报文结构介绍 在开始讲TCP连接过程时,还是先看看TCP报文的格式如图1所示.IP数据报此时由IP头部+TCP头部+TCP数据组成.不带选项的TCP头部是20字节长,而带选项的,TCP头部最长可达 ...

  9. TCP详解——传输控制协议(总述)

    初次熟读TCP,随着TCP的发展路线对他深入了解,真心觉得TCP协议的美妙之处.他比UDP这家伙更加可靠,深得我们信任.通过一个个英文简写,例如CRC.ARQ.RTT.ACK.SACK.DACK等,组 ...

随机推荐

  1. java web面试

    1. session和cookie的区别和联系,session的生命周期,多个服务部署时session管理. 原博http://blog.csdn.net/shuaishenkkk/article/d ...

  2. 谈谈如何从Apache官网扒文档

    学习java的猴子至少要会看文档, 一.从Apache官网下载文档 进入官网--components--例如点击FileUpload--点击最下面browser download area--点击bi ...

  3. C#创建datatable (转)

      C#创建datatable 方法一: DataTable tblDatas = new DataTable("Datas"); DataColumn dc = null; dc ...

  4. PHP批量上传一次点击选中多个

    首先前端部分需要设置好控件,这里使用HTML5 中 input 的新增属性 multiple 可以很好的解决了以往上传多个需要点击多次"上传按钮"的麻烦: <form act ...

  5. PHP之Mysql常用SQL语句示例的深入分析

    1.插入数据insert into表名(列名1,列名2,列名..) values(值1,值2,值...); insert into product(name, price, pic_path) val ...

  6. Java Des加解密方法(c#加密Java解密)

    最近我们用Java把一个用.net编写的老系统重新做了翻版,但是登录还是用.net的登录.这样就会遇到一个比较棘手的问题,我们登录用的cookie信息都是.net用des加密的,但我们不得不用Java ...

  7. apache 运行php环境之困扰,无法加载多个不同的.html文件

    又是一个项目,为多个纯静态html页面h5游戏页,原本是一个简单得不能的项目,但是却多生了事端. 我按照apache的惯例,将文件上传到服务器的DocumentRoot目录,进行测试了. 刚开始使用目 ...

  8. TCP协议滑动窗口(一)——控制数据传输速率

    窗口大小:TCP头中一个16位的域,表示当前可用接受缓冲区大小.在每个TCP对等段连接初始化时,告诉对方自己的窗口大小(不一定是满额,假如满额65201字节,可能暂时通告5840字节).若客户端接受数 ...

  9. Mac bash rc

    ###################################### ########## .bashrc ###################################### cas ...

  10. CodeForces462B

    Appleman and Card Game Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & % ...