• TCP包结构

  一个TCP包结构如下:

  一个TCP包主要由TCP包头和数据部分组成,包头固定部分为20字节,选项和数据部分根据实际情况设置为4N(N可以为0)字节。

  1.16bit源端口和目的端口号,它可以确认数据的传输方向(暂不考虑更底层的包)

  2.32bit序号,它是为TCP包中数据部分进行编号的部分。假设要发送的数据有100M,由于受MSS( Maximum Segment Size 最大报文段长度)限制,一个TCP包是不可能传输完这100M的数据,于是需要将数据拆分,为了确保拆分传输后的数据能在接收端正确的拼接,就需要对每个拆分的数据包进行编号来传输。这样,这个32位的序号指的就是本包数据部分第一个字节是这个100M数据中的第多少个字节。例如:假设发送第一个包时,先取出这100M数据的前面1024个字节发送,这时这个包中32位序号就是1,然后取下一个1024字节传输,这个时候的数据部分的第一个字节是这100M数据的第1025个字节,所以这第二TCP包中32位的序列号就应该为1025。当序号超过2^32时,进行一个轮回,重新从0开始计数。

  3.32bit确认序号,和上面的32位序号类似,只不过它指的是期望收到的下一个包的数据部分的编号。

  4.4bit首部长度,单位为4字节,指的是一个TCP包中除去数据部分的长度,也就是包头固定部分+选项部分的长度,2^4 -1 = 15, 15*4字节=60字节,即包头固定部分为20字节,选项最多可以为40字节。

  5.标识位:

    URG:.........

    ACK:TCP包的Acknowledgement number有效位,1时表明Acknowledgement number有效,0表示Acknowledgement number无效,忽略Acknowledgement number字段。自tcp连接建立后,ACK必须为1。

    PSH:TCP包中有数据需要尽快传递给应用层使用,而不是将数据进行缓冲,等到缓冲区满了再投递给应用层。

    RST:..........

    SYN:TCP包的同步位

    FIN:表示这个方向的带数据的包传输已经完成,即发送FIN包的端没有带数据的包过来了,需要释放这个方向的连接。

  • TCP三次握手

  TCP三次握手过程:

  

  测试代码,server端:

 #include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> #define ECHO "yes,i see you!" int main ( int argc, char *argv[] )
{
int ret,rn;
int socketfd,acfd;
int socklen;
char buf[]; struct sockaddr_in hostaddr;
struct sockaddr_in clientaddr; socketfd = socket(AF_INET, SOCK_STREAM, );
if ( socketfd < )
{
perror("socket");
return -;
} memset((void *)&hostaddr, , sizeof(hostaddr));
hostaddr.sin_family = AF_INET;
hostaddr.sin_port = htons();
hostaddr.sin_addr.s_addr = htonl(INADDR_ANY); ret = bind(socketfd, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
if ( ret < )
{
perror("bind");
close(socketfd);
return -;
} ret = listen(socketfd, );
if ( ret < )
{
perror("listen");
close(socketfd);
return -;
} socklen = sizeof(struct sockaddr);
acfd = accept(socketfd, (struct sockaddr *)&clientaddr, &socklen);
if ( acfd < )
{
perror("accept");
close(socketfd);
return -;
} while ()
{
memset(buf, 0x0, sizeof(buf));
rn = read(acfd, buf, sizeof(buf));
printf("%s\n",buf);
}
//write(acfd, ECHO, sizeof(ECHO)); close(acfd);
close(socketfd); return ;
}

  client端:

 #include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> #define HI "hi,can you see me?" int main ( int argc, char *argv[] )
{
int ret;
int socketfd,acfd;
int socklen;
struct sockaddr_in hostaddr;
char buf[]; socketfd = socket(AF_INET, SOCK_STREAM, );
if ( socketfd < )
{
perror("socket");
return -;
} memset((void *)&hostaddr, , sizeof(hostaddr));
hostaddr.sin_family = AF_INET;
hostaddr.sin_port = htons();
hostaddr.sin_addr.s_addr = htonl(INADDR_ANY); socklen = sizeof(struct sockaddr);
acfd = connect(socketfd, (struct sockaddr *)&hostaddr, sizeof(hostaddr));
if ( acfd < )
{
perror("connect");
close(socketfd);
return -;
} write(socketfd, HI, sizeof(HI)); //memset(buf, 0x0, sizeof(buf));
//read(socketfd, buf, sizeof(buf));
//printf("%s\n",buf); close(socketfd);
return ;
}

  这是CS间一对一的连接方式,各自完成一次收发。先运行server端,在accept下一行下断点,再运行client端,在connet的下一行下断点,使用wireshark抓包,过滤端口为6666的tcp包 tcp.port ==  ,运行,再断点处停下来时,可以看到抓到了3个包:

  这就是TCP三次握手的3个包,TCP的握手是发生在client端进行connect时。

  对于握手包的Sequence number和Acknowledgment number我理解为三次握手的包序。这里有RFC 793的解释:

  Sequence Number: 32 bits The sequence number of the first data octet in this segment (except when SYN is present). If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.

  Acknowledgment Number: 32 bits If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive. Once a connection is established this is always sent.

  第一次握手:

    client:"server,我要找你了!(SYN == 1),这是我第一次和你说话(Seq num == 0)" ,TCP包如下:

    可以看到Source port:33335,Destination port:6666,说明是C--->S这个方向传输的,Sequence为0,SYN被置位,没有数据部分。

  第二次握手:

    server:"client我听到你叫我了(ACK = = 1),你听到我的回应了吗(SYN == 1)?,这是我第一次和你说话(Seq num == 0),我等你第二次和我说话(Ack num == 1)",TCP包如下:

    可以看到Source port:6666,Destination port:33335,说明是S--->C这个方向传输的,Sequence num为0,Ack num为 1,SYN,ACK被置位,没有数据部分。

  第三次握手:

    clinet:"server,知道你听到我了(ACK ==  1),我们可以开聊了,这是我第二次和你说话(Seq num == 1),我等你和我第二次说话(Ack num == 1)"

    

    可以看到Source port:33335,Destination port:6666,说明是C--->S这个方向传输的,Sequence num为1,Ack num为 1,ACK被置位,没有数据部分。

  • 为什么要三次握手

  结合网上搜索,我觉得这是由于TCP是可靠的全双工的传输协议。首先,为什么要握手?因为需要确保可靠。为什么要3次,因为3次是理论上确保全双工握手成功的最少次数。对于单工,确保一次通信可以需要:1发送方把数据发送出去(SYN),2接收方回应发送方接收成功(ACK),这样形成了一个闭环。看看三次握手怎么做的:

  第一次: CLIENT----syn----->SERVER

  第二次: SERVER----ack,syn---->CLIENT

  第三次: CLIENT----ack----->SERVER

  这样,从client---->server, server---->client各自通过一次syn,ack形成闭环,理论上形成了一个近似可靠的通信。为什么说是近似可靠?因为完全可靠的通信是不存在的,见谢希仁<<计算机网络>>里面讲的红团蓝团问题。

  • TCP数据的传输

  握手成功后,开始传输第一个分节的数据,一次数据的传输需要2个TCP包。数据发送包,接收方应答包。

  1.Client---data--->Server:

  

  2.Server---ack--->Client

  • TCP的四次挥手

    四次挥手的时序

  一般来说,网络编程的CS模型中,服务端可以认为是一直不退出的,并且它是被动的一放,因此一般需要断开连接都是由客户端主动提出。

  类似于TCP的三次握手,四次挥手的四步:

    Client---fin,ack--->Server

    Server---ack---->Clinet

    Server---fin,ack--->Client

    Client----ack----->Server

  先把2次发送FIN的包中的ACK(未着色的)忽略,因为TCP建立连接后ACK必须置位。类似于三次握手的分析,一对FIN--ACK包的往来,形成一个闭环,保证了单侧通信的可靠。对比于三次握手,为什么不把四次挥手中间2个包合并呢?它们都是S-->C为什么要单独拆分来发送呢?注意到FIN的意义:表示这个方向的带数据的包传输已经完成,即发送FIN包的端没有带数据的包过来了,需要释放这个方向的连接。。那么接收到FIN包的这一方虽然不再接收对端的带数据的包,但是它仍然可以发带数据的包过去。

  以后补充

  http://blog.csdn.net/xifeijian/article/details/12777187

  http://blog.csdn.net/dog250/article/details/5747549

TCP三次握手,数据传输,四次挥手的更多相关文章

  1. 使用 tcpdump 抓包分析 TCP 三次握手、四次挥手与 TCP 状态转移

    目录 文章目录 目录 前文列表 TCP 协议 图示三次握手与四次挥手 抓包结果 抓包分析 TCP 三次握手 数据传输 四次挥手 TCP 端口状态转移 状态转移 前文列表 <常用 tcpdump ...

  2. 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

    重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...

  3. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

  4. TCP‘三次握手’和‘四次挥手’(通俗易懂)

      概述 我们都知道 TCP 是 可靠的数据传输协议,UDP是不可靠传输,那么TCP它是怎么保证可靠传输的呢?那我们就不得不提 TCP 的三次握手和四次挥手. 三次握手 下图为三次握手的流程图 下面通 ...

  5. 【转】TCP三次握手和四次挥手全过程及为什么要三次握手解答

    TCP三次握手和四次挥手的全过程   TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种表示: SYN(synchronous建立连接) ...

  6. [ 转载 ] Tcp三次握手和四次挥手详解

    #TCP的报头: 源端口号:表示发送端端口号,字段长为16位.目标端口号:表示接收端口号,字段长为16位.序列号:表示发送数据的位置,字段长为32位.每发送一次数据,就累加一次该数据字节数的大小.注意 ...

  7. 网络协议-网络分层、TCP/UDP、TCP三次握手和四次挥手

    网络的五层划分是什么? 应用层,常见协议:HTTP.FTP 传输层,常见协议:TCP.UDP 网络层,常见协议:IP 链路层 物理层 TCP 和 UDP 的区别是什么 TCP/UDP 都属于传输层的协 ...

  8. TCP三次握手与四次挥手详解

    目录 TCP三次握手与四次挥手详解 1.TCP报文格式 2.TCP三次握手 3.TCP四次挥手 4.为什么建立连接需要三次握手? 5.为什么断开连接需要四次挥手? 6.为什么TIME_WAIT状态还需 ...

  9. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  10. 学习 TCP 三次握手和四次挥手

    TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 本篇尝试使用动画来对这个知识点进行讲解,期望读者们可以更加简单地 ...

随机推荐

  1. xshell 通过ssh连接 ubuntu15_x64

    参考: http://www.cnblogs.com/wuyuegb2312/archive/2013/03/28/2986963.html 中文乱码在客户端xshell解决:http://jingy ...

  2. Medoo个人修改版

    Medoo是一款轻量级的php数据库操作类,下面不会介绍Medoo的使用方法,想学习Medoo请前往官网自学:http://medoo.in/ 在接触Medoo之前,一直是用自己写的php数据库操作类 ...

  3. 点击div全选中再点击取消全选div里面的文字

    想做一个就是点击一个div然后实现的功能是div里面的文字都成选中状态,然后就可以利用浏览器的自带的复制功能,任意复制在哪里去了 在网上百度了一下 然后网上的答案感觉很大的范围 然后一些搜索 然后就锁 ...

  4. 图解.NET Stack和Heap的本质区别

    现在越来越觉得对.NET基本概念的理解和掌握对于提升编程水平的重要性,先从.NET的 Stack(栈)和Heap(堆)说起,计算机的内存可以分为代码块内存,stack内存和heap内存.代码块内存是在 ...

  5. Heatmap.js v2.0 – 最强大的 Web 动态热图

    Heatmap 是用来呈现一定区域内的统计度量,最常见的网站访问热力图就是以特殊高亮的形式显示访客热衷的页面区域和访客所在的地理区域的图示.Heatmap.js 这个 JavaScript 库可以实现 ...

  6. [js开源组件开发]数字或金额千分位格式化组件

    数字或金额千分位格式化组件 这次距离上一个组件<[js开源组件开发]table表格组件>时隔了一个月,由于最近的项目比较坑,刚挖完坑,所以来总结性提出来几个组件弥补这次的空缺,首先是金额和 ...

  7. sublime安装

    1.sublime下载安装 下载地址:http://www.sublimetext.com/3 选择合适版本下载 2.自定义快捷键 Ctrl+Shift+P调出命令面板 3.自定义设置 Ctrl+Sh ...

  8. 探究TCP

    OSI OSI是Open System Interconnection的缩写,意为开放式系统互联.国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信 ...

  9. Atitit jOrgChart的使用  组织架构图css html

    Atitit jOrgChart的使用  组织架构图css html 1. 项目要做组织架构图,要把它做成自上而下的树形结构,于是决定1 2. Html导入 以来的css js1 2.1. 数据来源 ...

  10. What is research (1)

    This abstract tells me a lot of stories about itself. Here I want to discuss two stories about it. I ...