TCP数据包结构: TCP数据包是由“以太网首部,IP头部,TCP头部和用户数据”四部分组成。

一、ARP数据包结构

1、以太网头部

/* addr[6]表示6个字节的以太网地址。Representation of a 48-bit Ethernet address. */

struct uip_eth_addr {

  u8_t addr[6];

};

//uip_eth_hdr型结构:以太网首部有14字节:接收方MAC地址(6个字节),发送方MAC地址(6个字节),以太网帧的类型(2个字节)

struct uip_eth_hdr {

  struct uip_eth_addr dest; //uip_eth_addr结构成员是字节型数组addr[6],存放目的MAC地址

  struct uip_eth_addr src;  //uip_eth_addr结构成员是字节型数组addr[6],存放源MAC地址

  u16_t type;

         //太网帧的类型

         //0x0800表示后面跟着的是IPV4数据包;

         //0x0806表示后面跟着的是ARP数据包;

         //0x86dd表示后面跟着的是IPV6数据包;

};

2ARP数据包结构

struct arp_hdr

{

  struct uip_eth_hdr ethhdr;

  /*以太网首部有14字节:接收方MAC地址(6个字节),发送方MAC地址(6个字节),以太网帧的类型(2个字节)*/

  u16_t hwtype; //硬件类型,若是以太网,值是0x0001

  u16_t protocol;//协议类型,若是ipv4,值是0x0800

  u8_t hwlen;    //硬件长度,定义物理地址(MAC地址)的长度,若是mac地址就是6

  u8_t protolen; //协议长度,定义逻辑地址(IP地址)的长度,若是ip地址就是4

  u16_t opcode;

  /*操作码:定义ARP分组是请求还是应答。ARP请求是1,ARP回复是2,RARP请求是3,RARP回复是4*/

  struct uip_eth_addr shwaddr;  //发送方的6字节mac地址

  u16_t sipaddr[2];             //发送方的4字节ip地址

  struct uip_eth_addr dhwaddr;  //接收方的6字节mac地址

  u16_t dipaddr[2];             //接收方的4字节ip地址

};

二、TCP数据包结构

TCP数据包是由“以太网首部,IP头部,TCP头部和用户数据”四部分组成。

1、以太网首部

以太网首部有14字节:接收方MAC地址(6个字节),发送方MAC地址(6个字节),以太网帧的类型(2个字节)

struct uip_eth_addr {

  u8_t addr[6];

};

struct uip_eth_hdr {

  struct uip_eth_addr dest; //uip_eth_addr结构成员是字节型数组addr[6],存放目的MAC地址

  struct uip_eth_addr src;  //uip_eth_addr结构成员是字节型数组addr[6],存放源MAC地址

  u16_t type;

         //报文类型

         //0x0800表示后面跟着的是IPV4数据包;

         //0x0806表示后面跟着的是ARP数据包;

         //0x86dd表示后面跟着的是IPV6数据包;

};

2TCPIP头部

协议:

#define UIP_PROTO_ICMP  1   //ICMP协议编号定义为1

#define UIP_PROTO_TCP   6   //TCP协议编号定义为6

#define UIP_PROTO_UDP   17  //TCP协议编号定义为17

#define UIP_PROTO_ICMP6 58  //ICMP6协议编号定义为58

/* The TCP and IP headers. */

typedef u16_t uip_ip6addr_t[8];

//uip_ip6addr_t[]数组有8个元素,每个元素都是u16_t型。

//使用typedef修饰后,uip_ip6addr_t就变成了数据类型,可以用来声明u16型数组,且数组元素数量为8

struct uip_tcpip_hdr {

#if UIP_CONF_IPV6

  /* IPV6头部,IPv6 header. */

  u8_t vtc;

  u8  tcflow;

  u16_t flow;

  u8_t len[2];

  u8_t proto;

  u8_t  ttl;

  uip_ip6addr_t  srcipaddr;  //发送方IP地址占8个字节

  uip_ip6addr_t  destipaddr; //接收方IP地址占8个字节

#else

  //IP头部/IPV4头部(IPv4 header),20个字节

  u8_t  vhl;

//IP版本和IP头部长度:

//版本(Version):0x45 的高4位为0x04表示IPv4版本

//头部长度(Header Length):低4位为0x05,表示IPv4头部长度,单位为32位字

//即IP头部/IPV4头部为:5 * 4 = 20 字节。

  u8_t  tos;         //服务类型

  u8_t  len[2];      //IP报文总长度2个字节

  u8_t  ipid[2];     //标识,2字节,用于分片重组

  u8_t  ipoffset[2]; //标志字段和片偏移字段

/*标志字段第1位(保留位,bit15)始终为0;

标志字段第2位(DF位,bit14),DF=1禁止对该数据包分片;DF=0允许分片;

标志字段第3位(MF位,bit13),MF=1表示后续还有分片;MF=0表示当前是最后一个分片;

片偏移字段占13位,bit12:0,表示“当前分片”在原始数据包中的起始位置。

计算方式:偏移值 = 起始字节数 / 8。如果偏移值为5,则表示分片在原始数据包中,是从第5*8=40字节开始。*/

  u8_t  ttl;         //生存时间

  u8_t  proto;       //协议:1字节,6表示TCP

  u16_t ipchksum;    //检验和

  u16_t srcipaddr[2];//发送方IP地址,4字节

 u16_t  destipaddr[2];//接收方IP地址,4字节

#endif

 

//TCP头部(TCP header)总共为20字节

//但是,在某些场合,特别是在处理选项(Options)时,TCP头部的长度为24字节。

  u16_t srcport;  //发送方端口

  u16_t destport; //接收方端口

  u8_t seqno[4];  //序列号

  u8_t  ackno[4]; //确认号

  u8_t  tcpoffset;//数据偏移

  u8_t  flags;

/*标志位

URG:bit5紧急指针有效,表示数据需立即处理 。

ACK:bit4确认应答,用于确认数据已接收 。

PSH:bit3推送数据,要求接收方立即传递给应用层 。

RST:bit2重置连接,强制断开异常连接 。

SYN:bit1同步标志,用于建立连接并设置初始序列号

FIN:bit0结束标志,表示发送方完成数据传输*/

  u8_t  wnd[2];   //窗口大小, 告诉接收方,当前“发送方接收的缓冲区”的大小

  u16_t tcpchksum; //校验和

  u8_t urgp[2];    //紧急指针

  u8_t optdata[4];

         //最大段字节数1个字节,MSS选项的长度占1个字节,最大段高8数值,最大段低8数值

};

三、校验和程序

//函数功能:将“大端存储方式”的data[]中的前len个字节按照“双字节进行累加和校验”

//data为“待校验数据缓存”的起始地址

//len为待校验数据的字节总数

static u16_t chksum(u16_t sum, const u8_t *data, u16_t len)

{

  u16_t t;

  const u8_t *dataptr;

  const u8_t *last_byte;

  dataptr = data;             //指向“待校验数据缓存”的起始地址

  last_byte = data + len - 1; //指向“待校验数据缓存”的结束地址

 

  while(dataptr < last_byte)//至少有两个字节才能执行此while循环

         {

    t = (dataptr[0] << 8) + dataptr[1];//生成“大端存储方式”的16位整型数据

    sum += t;//计算“累加和”

    if(sum < t)//sum越过0x0000,发生进位

                   {

      sum++;//若有进位,则加1

    }

    dataptr += 2;//修改指针,为下次计算“累加和”做准备

  }

 

  if(dataptr == last_byte)//剩余一个字节

         {

    t = (dataptr[0] << 8) + 0;//生成“大端存储方式”的16位整型数据

    sum += t;//计算“累加和”

    if(sum < t)//sum越过0x0000,发生进位

                   {

      sum++;//若有进位,则加1

    }

  }

  return sum;//按照“大端存储方式”返回sum

}

//函数功能:data[]中的前len个字节按照双字节进行累加和校验

u16_t uip_chksum(u16_t *data, u16_t len)

{

         u16_t sum;

         sum=chksum(0, (u8_t *)data, len);

         //将“大端存储方式”的data[]中的前len个字节按照“双字节进行累加和校验”

  return htons(sum);

         //sum转换为“小端端存储方式”返回,因为KEIL使用的是小端存储方式

}

//函数功能:将“大端存储方式”的首地址为&uip_buf[14]的缓存中的前20个字节按照“双字节进行累加和校验”

//计算IP头部校验和

u16_t uip_ipchksum(void)

{

  u16_t sum;

         u8_t *tmpIPDataPointer;

         tmpIPDataPointer=&uip_buf[UIP_LLH_LEN];

  sum = chksum(0, tmpIPDataPointer, UIP_IPH_LEN);

//将“大端存储方式”的tmpIPDataPointer[]中的前20个字节按照“双字节进行累加和校验”

//定义UIP_LLH_LEN=14IP头的大小为UIP_IPH_LEN=20

  DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum);

  return (sum == 0) ? 0xffff : htons(sum);

         //htons()将累加和sum按照小端存储方式返回

}

//计算“上层长度,IP协议,发送方IP和接收方IPTCP头和数据”的校验和

//proto=UIP_PROTO_TCP   6   //TCP协议

//proto=UIP_PROTO_UDP   17  //UDP协议编

//proto=UIP_PROTO_ICMP6 58  //ICMP6协议

static u16_t upper_layer_chksum(u8_t proto)

{

  u16_t upper_layer_len;

  u16_t sum;

 

#if UIP_CONF_IPV6

  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]);

#else

  upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN;

         //上层长度upper_layer_len = IP报文总长度 - IP头的大小

#endif

  sum = upper_layer_len + proto;

  /*累加“上层长度和IP协议”时,无需考虑进位。

         IP protocol and length fields. This addition cannot carry. */

  sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t));

         /* 发送方IP和接收方IP需要考虑累加时考虑进位。Sum IP source and destination addresses. */

  sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],upper_layer_len);

         /*累加“TCP头和数据”时需要考虑加法进位。 Sum TCP header and data. */

   

  return (sum == 0) ? 0xffff : htons(sum);

}

u16_t uip_tcpchksum(void)

{

  return upper_layer_chksum(UIP_PROTO_TCP);

}

四、TCP客户端连接到TCP服务器

1、计算机发送ARP请求,60个字节

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x08 0x06 0x00 0x01 0x08 0x00 0x06 0x04 0x00 0x01 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0xC0 0xA8 0x01 0xBE 0x00 0x00 0x00 0x00 0x00 0x00 0xC0 0xA8 0x01 0x11 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

以太网首部“目的mac地址addr[6]”

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

以太网首部“源MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“以太网帧的类型type”

0x08 0x06,表示ARP协议

ARP头部“硬件类型hwtype”

0x00 0x01

ARP头部“协议类型protocol”

0x08 0x00,表示协议类型为ipv4

ARP头部“硬件长度hwlen”

0x06,表示MAC地址长度为6个字节

ARP头部“协议长度protolen”

0x04,表示IP地址长度为4个字节

ARP头部“操作码opcode”

0x00 0x01,表示ARP请求

ARP头部“发送方MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

ARP头部“发送方IP地址sipaddr[2]”

0xC0 0xA8 0x01 0xBE,表示192.160.1.190

ARP头部“接收方MAC地址addr[6]”

0x00 0x00 0x00 0x00 0x00 0x00

ARP头部“接收方IP地址dipaddr [2]”

0xC0 0xA8 0x01 0x11,表示192.160.1.17

总字节数小于60个字节,则填充数据

0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

2ENC28J60发送ARP应答,42个字节

0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x00 0x08 0xDC 0x11 0x11 0x02 0x08 0x06 0x00 0x01 0x08 0x00 0x06 0x04 0x00 0x02 0x00 0x08 0xDC 0x11 0x11 0x02 0xC0 0xA8 0x01 0x11 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0xC0 0xA8 0x01 0xBE

以太网首部“目的mac地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“源MAC地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“以太网帧的类型type”

0x08 0x06,表示ARP协议

ARP头部“硬件类型hwtype”

0x00 0x01

ARP头部“协议类型protocol”

0x08 0x00,表示协议类型为ipv4

ARP头部“硬件长度hwlen”

0x06,表示MAC地址长度为6个字节

ARP头部“协议长度protolen”

0x04,表示IP地址长度为4个字节

ARP头部“操作码opcode”

0x00 0x02,表示ARP应答

ARP头部“发送方MAC地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

ARP头部“发送方IP地址sipaddr[2]”

0xC0 0xA8 0x01 0x11,表示192.160.1.17

ARP头部“接收方MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

ARP头部“接收方IP地址dipaddr [2]”

0xC0 0xA8 0x01 0xBE,表示192.160.1.190

3、计算机发送62个字节

0x00 0x08 0xDC 0x11 0x11 0x02 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x08 0x00 0x45 0x00 0x00 0x30 0xB8 0x7C 0x40 0x00 0x80 0x06 0xBE 0x2B 0xC0 0xA8 0x01 0xBE 0xC0 0xA8 0x01 0x11 0x06 0x10 0x13 0x88 0x68 0xAA 0x4C 0x64 0x00 0x00 0x00 0x00 0x70 0x02 0xFA 0xF0 0x35 0x68 0x00 0x00 0x02 0x04 0x05 0xB4 0x01 0x01 0x04 0x02

以太网首部“目的mac地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“源MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x30,表示报文长度有48个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0xB8 0x7C,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x40 0x00, 禁止对该数据包分片

IPV4头部的生存时间u8_t ttl

0x80

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xBE 0x2B

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

TCP头部的发送方端口u16_t srcport

0x06 0x10,表示发送方端口为1552

TCP头部的接收方端口u16_t destport

0x13 0x88,表示接收方端口为5000

TCP头部的序列号u8_t seqno[4]

0x68 0xAA 0x4C 0x64

TCP头部的标志位flags的bit1=1表示这是“初始序列号”。

TCP头部的确认号u8_t ackno[4]

0x00 0x00 0x00 0x00

告诉接收方,期望接收到以“这个以确认号”为序列号的数据包。

TCP头部的数据偏移u8_t tcpoffset

0x70

TCP头部总长度7*4=28字节

TCP头部的标志位u8_t flags

0x02

SYN=1,bit1用于建立连接并设置“初始序列号”;

TCP头部的窗口大小u8_t wnd[2]

0xFA 0xF0

指示计算机接收的缓冲区大小为64240个字节

TCP头部的校验和u16_t tcpchksum

0x35 0x68

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

TCP头部中的数据

0x02 0x04 0x05 0xB4 0x01 0x01 0x04 0x02

4ENC28J60应答58个字节

0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x00 0x08 0xDC 0x11 0x11 0x02 0x08 0x00 0x45 0x00 0x00 0x2C 0x00 0x01 0x00 0x00 0x40 0x06 0xF6 0xAB 0xC0 0xA8 0x01 0x11 0xC0 0xA8 0x01 0xBE 0x13 0x88 0x06 0x10 0x00 0x00 0x00 0x10 0x68 0xAA 0x4C 0x65 0x60 0x12 0x05 0xA6 0x3F 0xA7 0x00 0x00 0x02 0x04 0x05 0xA6

以太网首部“目的mac地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“源MAC地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x2C,表示报文长度有44个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0x00 0x01,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x00 0x00

DF=0允许分片; MF=0表示当前是最后一个分片,也就是没有分片。

IPV4头部的生存时间u8_t ttl

0x40

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xF6 0xAB

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

TCP头部的发送方端口u16_t srcport

0x13 0x88,表示发送方端口为5000

TCP头部的接收方端口u16_t destport

0x06 0x10,表示接收方端口为1552

TCP头部的序列号u8_t seqno[4]

0x00 0x00 0x00 0x10

TCP头部的标志位flags的bit1=1表示这是“初始序列号”,使用接收到的“确认号”作为序列号。

TCP头部的确认号u8_t ackno[4]

0x68 0xAA 0x4C 0x65

告诉接收方,我已收到以“0x68 0xAA 0x4C 0x64”为序列号的数据包

TCP头部的数据偏移u8_t tcpoffset

0x60

TCP头部总长度6*4=24字节

TCP头部的标志位u8_t flags

0x12

SYN=1,bit1用于建立连接并设置“初始序列号”;

ACK=1,bit4确认应答,用于确认数据已接收 。

TCP头部的窗口大小u8_t wnd[2]

0x05 0xA6

指示ENC28J60的接收缓冲区大小为1446个字节

TCP头部的校验和u16_t tcpchksum

0x3F 0xA7

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

TCP头部中的数据

0x02 0x04 0x05 0xA6

5、计算机发送60个字节

0x00 0x08 0xDC 0x11 0x11 0x02 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x08 0x00 0x45 0x00 0x00 0x28 0xB8 0x7D 0x40 0x00 0x80 0x06 0xBE 0x32 0xC0 0xA8 0x01 0xBE 0xC0 0xA8 0x01 0x11 0x06 0x10 0x13 0x88 0x68 0xAA 0x4C 0x65 0x00 0x00 0x00 0x11 0x50 0x10 0xFA 0xF0 0x62 0x0B 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

以太网首部“目的mac地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“源MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x28,表示报文长度有40个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0xB8 0x7D,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x40 0x00, 禁止对该数据包分片

IPV4头部的生存时间u8_t ttl

0x80

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xBE 0x32

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

TCP头部的发送方端口u16_t srcport

0x06 0x10,表示发送方端口为1552

TCP头部的接收方端口u16_t destport

0x13 0x88,表示接收方端口为5000

TCP头部的序列号u8_t seqno[4]

0x68 0xAA 0x4C 0x65

使用接收到的“确认号”作为序列号。

TCP头部的确认号u8_t ackno[4]

0x00 0x00 0x00 0x11

告诉接收方,期望接收到以“0x00 0x00 0x00 0x10”为序列号的数据包。

TCP头部的数据偏移u8_t tcpoffset

0x50

TCP头部总长度5*4=20字节

TCP头部的标志位u8_t flags

0x10

ACK=1,bit4确认应答,用于确认数据已接收

TCP头部的窗口大小u8_t wnd[2]

0xFA 0xF0

指示计算机接收的缓冲区大小为64240个字节

TCP头部的校验和u16_t tcpchksum

0x62 0x0B

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

填充数据

0x00 0x00 0x00 0x00 0x00 0x00

五、TCP客户端向TCP服务器发送数据,服务器将收到的数据回传

注意:服务器不会主动向客户端传送数据。

1、计算机发送60个字节

0x00 0x08 0xDC 0x11 0x11 0x02 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x08 0x00 0x45 0x00 0x00 0x2E 0xB8 0x82 0x40 0x00 0x80 0x06 0xBE 0x27 0xC0 0xA8 0x01 0xBE 0xC0 0xA8 0x01 0x11 0x06 0x10 0x13 0x88 0x68 0xAA 0x4C 0x71 0x00 0x00 0x00 0x17 0x50 0x18 0xFA 0xEA 0xBB 0x3A 0x00 0x00 123ABC

以太网首部“目的mac地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“源MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x2E,表示报文长度有46个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0xB8 0x82,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x40 0x00, 禁止对该数据包分片

IPV4头部的生存时间u8_t ttl

0x80

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xBE 0x27

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

TCP头部的发送方端口u16_t srcport

0x06 0x10,表示发送方端口为1552

TCP头部的接收方端口u16_t destport

0x13 0x88,表示接收方端口为5000

TCP头部的序列号u8_t seqno[4]

0x68 0xAA 0x4C 0x71

使用接收到的“确认号”作为序列号。

TCP头部的确认号u8_t ackno[4]

0x00 0x00 0x00 0x17

TCP头部的数据偏移u8_t tcpoffset

0x50

TCP头部总长度5*4=20字节

TCP头部的标志位u8_t flags

0x18

ACK=1,bit4确认应答,用于确认数据已接收 。

PSH=1,bit3推送数据,要求接收方立即传递给应用层

TCP头部的窗口大小u8_t wnd[2]

0xFA 0xEA

指示计算机接收的缓冲区大小为64234个字节

TCP头部的校验和u16_t tcpchksum

0xBB 0x3A

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

用户数据

“123ABC”

2ENC28J60应答60个字节

0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x00 0x08 0xDC 0x11 0x11 0x02 0x08 0x00 0x45 0x00 0x00 0x2E 0x00 0x05 0x00 0x00 0x40 0x06 0xF6 0xA5 0xC0 0xA8 0x01 0x11 0xC0 0xA8 0x01 0xBE 0x13 0x88 0x06 0x10 0x00 0x00 0x00 0x17 0x68 0xAA 0x4C 0x77 0x50 0x18 0x05 0xA6 0xB0 0x79 0x00 0x00 123ABC

以太网首部“目的mac地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“源MAC地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x2E,表示报文长度有46个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0x00 0x05,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x00 0x00

DF=0允许分片; MF=0表示当前是最后一个分片,也就是没有分片。

IPV4头部的生存时间u8_t ttl

0x40

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xF6 0xA5

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

TCP头部的发送方端口u16_t srcport

0x13 0x88,表示发送方端口为5000

TCP头部的接收方端口u16_t destport

0x06 0x10,表示接收方端口为1552

TCP头部的序列号u8_t seqno[4]

0x00 0x00 0x00 0x17

TCP头部的确认号u8_t ackno[4]

0x68 0xAA 0x4C 0x77

告诉接收方,我已收到以“0x68 0xAA 0x4C 0x71”为序列号的数据包

TCP头部的数据偏移u8_t tcpoffset

0x50

TCP头部总长度5*4=20字节

TCP头部的标志位u8_t flags

0x18

ACK=1,bit4确认应答,用于确认数据已接收 。

PSH=1,bit3推送数据,要求接收方立即传递给应用层

TCP头部的窗口大小u8_t wnd[2]

0x05 0xA6

指示ENC28J60的接收缓冲区大小为1446个字节

TCP头部的校验和u16_t tcpchksum

0xB0 0x79

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

用户数据

“123ABC”

3、计算机发送60个字节

0x00 0x08 0xDC 0x11 0x11 0x02 0xB4 0x2E 0x99 0x59 0xEC 0x1E 0x08 0x00 0x45 0x00 0x00 0x28 0xB8 0x83 0x40 0x00 0x80 0x06 0xBE 0x2C 0xC0 0xA8 0x01 0xBE 0xC0 0xA8 0x01 0x11 0x06 0x10 0x13 0x88 0x68 0xAA 0x4C 0x77 0x00 0x00 0x00 0x1D 0x50 0x10 0xFA 0xE4 0x61 0xF9 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

以太网首部“目的mac地址addr[6]”

0x00 0x08 0xDC 0x11 0x11 0x02

以太网首部“源MAC地址addr[6]”

0xB4 0x2E 0x99 0x59 0xEC 0x1E

以太网首部“以太网帧的类型type”

0x08 0x00,表示IPV4数据包类型

IPV4头部的IP版本和头部长度u8_t vhl

0x45,表示IPV4头部有4*5=20个字节

IPV4头部的服务类型u8_t tos

0x00

IPV4头部的IP报文总长度u8_t len[2]

0x00 0x28,表示报文长度有40个字节

它是IP头,TCP头部和用户数据的长度。

IPV4头部的标识u8_t ipid[2]

0xB8 0x83,表示数据包唯一ID,分片时,所有分片段使用相同ID,表示属于同一包数据。

IPV4头部的标志与片偏移u8_t ipoffset[2]

0x40 0x00, 禁止对该数据包分片

IPV4头部的生存时间u8_t ttl

0x80

IPV4头部的TCP协议u8_t proto

0x06,表示协议是TCP

IPV4头部的检验和u16_t ipchksum

0xBE 0x2C

IPV4头部的发送方IP地址u16_t srcipaddr[2]

0xC0 0xA8 0x01 0xBE

表示192.160.1.190

IPV4头部的接收方IP地址u16_t destipaddr[2]

0xC0 0xA8 0x01 0x11

表示192.160.1.17

TCP头部的发送方端口u16_t srcport

0x06 0x10,表示发送方端口为1552

TCP头部的接收方端口u16_t destport

0x13 0x88,表示接收方端口为5000

TCP头部的序列号u8_t seqno[4]

0x68 0xAA 0x4C 0x77

使用接收到的“确认号”作为序列号。

TCP头部的确认号u8_t ackno[4]

0x00 0x00 0x00 0x1D

告诉接收方,期望接收到以“0x00 0x00 0x00 0x17”为序列号的数据包。

TCP头部的数据偏移u8_t tcpoffset

0x50

TCP头部总长度5*4=20字节

TCP头部的标志位u8_t flags

0x10

ACK=1,bit4确认应答,用于确认数据已接收

TCP头部的窗口大小u8_t wnd[2]

0xFA 0xE4

指示计算机接收的缓冲区大小为64228个字节

TCP头部的校验和u16_t tcpchksum

0x61 0xF9

TCP头部的紧急指针u8_t urgp[2]

0x00 0x00

填充数据

0x00 0x00 0x00 0x00 0x00 0x00

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐