关于TCP之序号与确认号

 TCP/IP  关于TCP之序号与确认号已关闭评论
6月 152016
 

 

  1. tcp序号是两个方向的,每个方向有自己的序列号
  2. 依次发出的两个tcp数据包的序号可能相同、可能加1、也可能加更多,规则:
    1. 如果上个数据包不需要确认,则下个数据包的序号不增加
    2. 如果上个数据包没有数据,但是也需要确认,如SYN,则下个数据包的序号加1
    3. 如果上个数据包有n个数据,则下个数据包的序号加n
  3. 确认号比较简单,就是要确认的数据包的序号加1
  4. 确认包可以是包含在响应的数据包中的
  5. 不是每个数据包都要对应一个确认包的,一个确认包可以确认好几个数据包的,如:
    1. 由于接收方buffer比较大(就是tcp的win比较大),发送方连续发送了3个数据包,这时候,接收方可以只确认最后一个数据包就足以说明前两个数据包都已经收到了
 Posted by at 下午 6:08

wireshark 问题包分析

 TCP/IP  wireshark 问题包分析已关闭评论
6月 152016
 

问题包如下图:

138 数据包问题: 其实 138、139、140 三个包是在某个设备上因超过mtu值而被拆分的一个包; 138是首先被收到的一个子包,所以有此标识

140数据包问题: 其实从ip的标识头(序号自增)来看,140应该出现在139前面,所以说:Out-Of-Order (就是所谓的乱序)

139数据包问题: 从ip的标识头来看,139前面应该有一个数据包没被抓到(其实就是140),实际是迟到了那么几微妙; 也就是说,如果140数据包能赶到139前面,那么139和140的问题就都没有了

142数据包问题: 从tcp协议的seq来看,141和142是重复了; 从ip数据包来看,这不是同一个数据包的重传,至于为啥会重复ack,不知道啊!

 

问题: ip分包标识是在ip协议上的,这里的重组为什么是reassembled TCP Segments

 Posted by at 下午 5:56

UDP学习

 UDP  UDP学习已关闭评论
1月 232015
 

缘起

 

提问:

  1. send和sendto的区别?
  2. recv和recvfrom的区别?
 Posted by at 下午 12:21

Open Graph

 协议相关  Open Graph已关闭评论
6月 142014
 

Open Graph通讯协定(Protocol)本身是一种制定一套Metatags的规格,用来标注你的页面,告诉我们你的网页代表哪一类型的现实世界物件。另一伙伴网站,即Amazon旗下的Internet Movie Database(IMDb),将用这个Open Graph Protocol为每一部电影标注页面。按下IMDb上的“赞”按钮,就会自动把那部电影加入Facebook使用者profile中的“最爱的电影”。

 

使用示例: http://www.importnew.com/11317.html   其中点击分享到微博时,微博内容就是通过open graph标签得到的

 Posted by at 下午 1:35

QUIC协议

 协议相关  QUIC协议已关闭评论
6月 102014
 

 

相关参考:

http://lwn.net/Articles/558826/

https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/edit

http://en.wikipedia.org/wiki/QUIC

 

 

 Posted by at 上午 10:44

再谈代理与隧道

 http协议, TCP/IP  再谈代理与隧道已关闭评论
4月 252014
 

缘起

我的IE上访问 www.google.com.hk 是正常的;但是我的chrome上访问 www.google.com.hk 却报证书错误;

查看证书: 在IE上确实是正确的,在chrome上确实是错误的。

另: 由于www.google.com.hk 被解析到一个内网IP 192.168.xx.xx ;

问题:同是被解析到192.168.xx.xx ,为什么IE可以,而chrome不可以?

分析

抓包看看

chrome抓包结果:

IE访问时的抓包结果:

 

从抓包信息不难发现:

内网IP 192.168.xx.xx 提供了两种代理模式:

1.  7层代理模式:  chrome走的是这种模式

2.  HTTP隧道模式: IE走的是这种模式

通过nslookup查看www.google.com.hk解析到的IP地址为: 192.168.xx.xx ,如下

 

说明

该dns: 10.xx.xx.xx 提供了wpad.dat 文件(wpad参考资料:http://yuelei.blog.51cto.com/202879/83841/ );

似乎是:

IE参考该文件,通过HTTP隧道模式完成请求

chrome没有参考该文件,直接发起了请求

为什么会这样?

原本chrome的代理等设置是和IE相同的,如此看来,有可能不同了,去chrome的设置中看看,发现如下可以地方:

有没有发现,这里无法“更改代理服务器设置”,原因是: 您的网络代理设置有扩展程序管理  正常情况为:

 

去扩展程序中看看,我安装并启用了如下两个插件:

Proxy SwitchySharp

Unblock Youku

这两个插件都有此功能,全部禁用后,恢复正常:

最后

那么哪些域名会走隧道呢? 访问如下地址:

http://10.xx.xx.xx/wpad.dat

其中 10.xx.xx.xx 为你的dns服务器的IP地址;当然,也可能是dns告诉你的某个其他的IP地址,详情参考( http://yuelei.blog.51cto.com/202879/83841/ ),如下:

 

到此为止,浪费了1个小时

 Posted by at 上午 11:32

关于SO_REUSEADDR的用法

 Linux & Unix, TCP/IP  关于SO_REUSEADDR的用法已关闭评论
1月 052014
 

1. 一般来讲,在我们写一个server的时候,会用到SO_REUSEADDR,因为,当server正在工作的时候,需要重启,这时候,可能server的一些子进程还在工作,也或者一些连接还处于time_wait状态,而且time_wait状态的时间一般比较长,如果没有SO_REUSEADDR,则会因为端口被占用而bind失败,无法启动server,实例如下:

 

注意:

端口被占用后,不是listen是否能够成功,主要是bind能否成功。

 

2. 对于一个client来讲,如果总是疯狂地连接某个IP的同一个端口,并且连接完之后主动关闭连接,会导致大量的time_wait状态的连接,如果系统没有设置 net.ipv4.tcp_tw_reuse = 1 , 则会导致bind失败(虽然该bind的是隐式的)

 Posted by at 下午 11:45

关于代理

 TCP/IP  关于代理已关闭评论
11月 152013
 

一、 http代理服务器代理https请求(这个就是http隧道吧)

1) 打开连接

CONNECT passport.sina.cn:443 HTTP/1.1
Host: passport.sina.cn
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Linux; Android 4.1.1; MI 2 Build/JRO03L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.92 Mobile Safari/537.36

HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 20:01:27.916
Connection: close

2) 开始ssl握手(其实下面可以是任何的其他协议)

 

当使用CONNECT 时,代理服务器就只负责建立一个tcp连接通道,不再关心上层是什么协议了

二、普通的http代理

> GET http://phpor.net/test.php HTTP/1.1
> User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: login.sina.com.cn
> Pragma: no-cache
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Date: Fri, 15 Nov 2013 12:15:40 GMT
< Server: Apache

 

 Posted by at 下午 8:18

Response与Transfer-Encoding:chunked、Content-Length、Content-Encoding:gzip

 http协议  Response与Transfer-Encoding:chunked、Content-Length、Content-Encoding:gzip已关闭评论
8月 042013
 

缘起

了解HTTP 1.1和HTTP1.0的区别的同学都知道,Transfer-Encoding:chunked , Connection:keep-alive 都是HTTP 1.1的新特性;

Connection:keep-alive 使得一次连接可以干多次HTTP请求的活儿,而HTTP1.0协议每次tcp连接只能处理一个HTTP请求;

另外,对于HTTP 1.0来讲,如果一次HTTP的响应内容很多,而且又无法提前预知内容的多少,那么就不使用content-length ,输出完成后,直接关闭连接即可,一定程度上来讲,content-length对于HTTP 1.0来讲,是可有可无的;

而对于HTTP1.1 来讲,如果 connection: keep-alive ,而且又不能提前预知内容多少的话,该怎么办呢? 这就是为什么要有Transfer-Encoding:chunked 的原因了。

有了这些知识之后,我们再来看一种现象,为什么同样是HTTP1.1 ,有的请求就使用的是 content-length ,而又的请求就使用的Transfer-Encoding:chunked 呢? 需要什么特殊的设置吗?

可能请求输出的内容并不多,比如就10行,但是每行内容需要5s钟的时间来生成,如果能分块儿输出,是不是用户体验会好一些?那么又如何分块儿输出呢?

从协议上来讲,如果输出中有 content-length 则显然不是分块儿输出的,如果是Transfer-Encoding:chunked 则可能是分块儿输出的。

 

查资料:

一般服务器采用 Transfer-Encoding:chunked 有两种情况:

1. 应用程序已经输出给webserver很多内容(就是webserver的buffer满了),但是还是没有要结束的意思(就是还没输出完),则webserver放弃输出content-length,如果是HTTP1.0 ,则直接输出内容(输出完关闭连接就ok了);如果是HTTP1.1,则采用Transfer-Encoding:chunked 的方式输出。

2. 应用程序主动flush内容到客户端,如果是PHP,为: ob_flush(); flush(); (参看: http://php.net/flush )

 

所以: 对于页面服务,如果要输出的内容很多,可以生成一部分就flush一部分,让浏览器尽快渲染给用户,给用户一个更好的使用体验。

Content-Encoding:gzip

gzip是内容编码,是否压缩; 压缩式在传输之前进行的,所以传输的分块儿是按照压缩后的数据分块儿的(似乎有点儿废话了)

Nginx中如果启用了gzip压缩,则必然采用Transfer-Encoding:chunked 的方式输出,原因如下:

Nginx中Gzip模块和r->headers_out.content_length_n

r->headers_out.content_length_n :这个在Nginx内部用于表述请求返回内容的长度。但注意这不是完全相等的,只有在 r->headers_out.content_length_n >=0的时候,才有意义。比如说,通常后端的upstream(比如说PHP),如果没有在脚本中强制header输出content-length,则默认在nginx中 r->headers_out.content_length_n = -1。

Gzip模块也是一个典型的Filter模块。这里简单介绍下,后续可以详细描述。在header filter中会直接清空 r->headers_out.content_length_n和header中输出的content_length。为什么要清空呢?主要是因为gzip要对内容模块进行压缩处理,而在header filter的时候,gzip模块不可能计算出压缩后的内容长度(原因是在nginx中,header 输出和body的输出是完全两个不同的阶段),所以最好的办法就是在清空header中的content-length。这样结合之前的介绍的chunked模块,可以看出:在nginx中,如果采用gzip,如果是keep alive,则必然是chunked模式。

 

参考资料:

http://blog.xiuwz.com/tag/content-length/

http://lokki.iteye.com/blog/1072327

http://www.cnblogs.com/foxhengxing/archive/2011/12/02/2272387.html

 

 

 Posted by at 上午 12:39