tcp、http 学习小结
来源:互联网 发布:烂命鸳鸯知乎 编辑:程序博客网 时间:2024/06/11 15:51
tcp、http 学习小结
前言
最近因为cdn的一个问题,困扰了自己好久。因为需要统计网站访问的成功数,而且要求比较精确。目前的实现不能满足要求,因为没有区别访问成功与否,也没有对超时做处理。期间解决这个问题,走了不少弯路,现在在这里记录下来,为自己也为别人提供一个方便。
关键字
- tcp
- 1.tcp三次握手
- 2.tcp序列号,确认号
- 3.tcp 头部扩展option域
- http
- 1.http 1.0与http1.1
- 2.get,response
- 3.http 返回码
- wireshark
- 工具介绍
一.tcp小结
tcp头格式:
tcp结构体struct tcphdr
struct tcphdr { __u16 source; __u16 dest; __u32 seq; __u32 ack_seq;#if defined(__LITTLE_ENDIAN_BITFIELD) __u16 res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1;#elif defined(__BIG_ENDIAN_BITFIELD) __u16 doff:4, res1:4, cwr:1, ece:1, urg:1, ack:1, psh:1, rst:1, syn:1, fin:1;#else#error "Adjust your <asm/byteorder.h> defines"#endif __u16 window; __u16 check; __u16 urg_ptr;};
tcp建立连接与关闭连接
tcp建立连接需要经过三次握手syn->syn/ack->ack,三次握手每一步都是必需的,在网络环境比较差的时候,会发生握手包丢失,tcp会自动重复发送握手包,直到连接建立或者超时。
tcp建立连接时候的初始序列号并不是0,而是经过一种算法得到的,具体百度。这可以保证tcp序列号不至于错乱,在wireshark中显示的序列号是相对序列号,wireshark把每次syn的序列号作为基准0,这样的目的是看起来更直观。
syn:
syn/ack:
ack:
可以看出来初始序列号并不是0,每次的确认号表示的是期望下次从对方收到的序列号的值。序列号与确认号都是uint32_t类型,占据32位,达到最大又会从0开始。
类似的结束时候
tcp关闭连接是经过四次握手,建立连接经过三次握手,值得提出的是建立和关闭连接并不消耗序列号,只有成功建立或者关闭序列号才会加一,具体可以自己抓包分析下。
tcp option头部
上面的tsval,与tsecr是在tcp头部的扩展字段(kind)。本身并不包含于tcphdr结构体中,因为这是由后续rfc文档建议添加的字段,在tcp模块编写之后提出的。因为tcp option的存在,所以tcp头的长度一般不是20(tcp->doff == 4),tcp头最小是20bytes。
下面是kind字段意义列表:
其中我用到的是kind为8的字段,意思是在每个数据包上加上tcp时间戳。时间戳分为tsval与tsecr两个,分别由连接的两端进行维护,每次传输时需要在tsecr上对对方上次的数据包的时间戳进行确认,并在tsval加上自己最新的时间戳。
tcp时间戳并不是系统时间,通过date -d @776961691可以看到结果是Mon Aug 15 22:41:31 CST 1994,时间明显不对。tcp时间戳不采取系统时间的理由也很充分,每次同步时间都会导致时间突变,这就会导致时间戳也突变,这是不可取的。实际上tcp采用的是系统从开机以来的相对时间,这样只要不关机,就不会变化。系统默认每次HZ是250,这是在内核编译时指定的,也就是jiffies每增加一就是4ms的时间。因此可以通过两次tsval时间差计算出两次发包的时间间隔。
http://blog.csdn.net/zhandoushi1982/article/details/5536210
http
http是应用层协议,一般是建立在tcp之上的。也就是说http是面向用户,并不关心底层连接的实现。有句话叫做“http面向连接的,但是是无状态的”。这句话可以这么理解:基于tcp实现的http,每次发送请求都会先建立tcp连接,在连接建立之后发送http数据。然而http又是无记忆的,http并不知道自己已经发送过哪些数据,所以对于同样的请求,比如每次打开www.baidu.com,刷新页面都是重新发送的数据。http把这当作一次新的请求。
http数据是紧挨着tcp头之后的。
一个完整的包结构是这样的:
-{Ethernet | Ip | tcp/udp | HTTP}
http现在最流行的是http 1.1版本,相比于之前版本,效率提高了许多。http 1.0是短连接,每次传输数据会建立一个tcp连接,使用完毕立马关闭,下次使用重新建立连接。http 1.1则默认长连接,这在http头域connection选项中可以设置,值为close为短连接,keep-alive为长连接。
验证如下:
telnet www.baidu.com 80
输入:
GET / HTTP/1.1
两次回车,(这是因为http规定行末,以及头结束必须为\r\n)
GET / HTTP/1.0
http 1.0
http 1.1
先写这么多。。。
参考链接给在下面,懒得写了
http://blog.chinaunix.net/uid-8059407-id-2034302.html
http://www.cse.scu.edu/~dclark/am_256_graph_theory/linux_2_6_stack/linux_2tcp_8h-source.html
http://blog.csdn.net/mrwangwang/article/details/8537775
http://blog.csdn.net/zhandoushi1982/article/details/5536210
- tcp、http 学习小结
- TCP学习小结
- Http学习小结
- TCP和http学习笔记
- TCP和HTTP学习笔记
- TCP状态变迁图学习小结
- TCP/IP学习笔记-面试小结
- TCP小结
- TCP小结
- TCP小结
- TCP/IP、Http/Https、Socket理解学习
- Socket、Tcp、Udp、Http 知识点学习
- Golang 学习笔记:HTTP, TCP/IP, UDP
- Http小结
- HTTP小结
- HTTP小结
- tcp-http
- 《TCP/IP详解卷1》学习小结(一)------链接层
- 关于 safari浏览器 不支持new Date 显示NaN的问题记录
- 数组(二):ArrayList的实现和Arrays类的使用
- LintCode 主元素
- yolo v2 笔记
- 排序算法
- tcp、http 学习小结
- PC机安装ArchLinux详细步骤
- window系统,wamp下nginx配置TP使用
- Hibernate 一对一连接表单向关联
- PHP强制下载文件
- JSP开发实战一
- 软件框架和软件架构的区别?
- Hibernate 笔记二(多表设计之一对多)
- android 资源文件处理工具