<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Network on kamuszhou&#39;s blog</title>
    <link>https://ykyi.net/categories/network/</link>
    <description>Recent content in Network on kamuszhou&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 23 Nov 2018 08:45:32 +0000</lastBuildDate>
    <atom:link href="https://ykyi.net/categories/network/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>netstat -s统计输出的所有字段详细解释</title>
      <link>https://ykyi.net/?p=1557/</link>
      <pubDate>Fri, 23 Nov 2018 08:45:32 +0000</pubDate>
      <guid>https://ykyi.net/?p=1557/</guid>
      <description>&lt;p&gt;今天工作上碰到一个问题需要知道udp的丢包数据。实际上我不相信能简单地得到udp的丢包精确数据。理由是，网卡负载太高时有些包连网卡都没收到，根本不可能来得及汇报给内核。另外，如果是路由器把udp丢了，那udp的目的端机器当然更不可能感知到有丢包了。&lt;/p&gt;
&lt;p&gt;这时，同事说netstat -us (–statistic)可以看到udp的丢包。这里的u选项指的是只展示udp相关的统计，s选项自然表示的是统计了。如果不用u选项，则出显示所有统计数据。下面是我的机器上的输出。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;Ip:
    203440255187 total packets received
    0 forwarded
    0 incoming packets discarded
    201612429535 incoming packets delivered
    1064529177 requests sent out
    15 fragments dropped after timeout
    3058122492 reassemblies required
    1230296840 packets reassembled ok
    15 packet reassembles failed
Icmp:
    14869220 ICMP messages received
    3965512 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 6054246
        timeout in transit: 687
        echo requests: 8570532
        echo replies: 243755
    12913011 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 4097869
        time exceeded: 5
        echo request: 244605
        echo replies: 8570532
IcmpMsg:
        InType0: 243755
        InType3: 6054246
        InType8: 8570532
        InType11: 687
        OutType0: 8570532
        OutType3: 4097869
        OutType8: 244605
        OutType11: 5
Tcp:
    111681768 active connections openings
    4186820 passive connection openings
    24951865 failed connection attempts
    55064041 connection resets received
    275 connections established
    1033901799 segments received
    1776166765 segments send out
    12156205 segments retransmited
    6705 bad segments received.
    106348033 resets sent
Udp:
    198894689917 packets received
    472986510 packets to unknown port received.
    1146976531 packet receive errors
    116750744 packets sent
    110301286 receive buffer errors
    0 send buffer errors
UdpLite:
TcpExt:
    423 invalid SYN cookies received
    693 packets pruned from receive queue because of socket buffer overrun
    19 packets pruned from receive queue
    11309370 TCP sockets finished time wait in fast timer
    106 packets rejects in established connections because of timestamp
    10210477 delayed acks sent
    20811 delayed acks further delayed because of locked socket
    Quick ack mode was activated 8856 times
    17118697 packets directly queued to recvmsg prequeue.
    301717551 bytes directly in process context from backlog
    152118951904 bytes directly received in process context from prequeue
    104771733 packet headers predicted
    15179703 packets header predicted and directly queued to user
    218747377 acknowledgments not containing data payload received
    102637644 predicted acknowledgments
    7293 times recovered from packet loss by selective acknowledgements
    Detected reordering 40 times using FACK
    Detected reordering 27 times using SACK
    Detected reordering 1088 times using time stamp
    476 congestion windows fully recovered without slow start
    5287 congestion windows partially recovered using Hoe heuristic
    236 congestion windows recovered without slow start by DSACK
    151673 congestion windows recovered without slow start after partial ack
    1 timeouts after reno fast retransmit
    4 timeouts after SACK recovery
    10540 timeouts in loss state
    7232 fast retransmits
    649 forward retransmits
    1871 retransmits in slow start
    11612658 other TCP timeouts
    TCPLossProbes: 93185
    TCPLossProbeRecovery: 14667
    2431 packets collapsed in receive queue due to low socket buffer
    8814 DSACKs sent for old packets
    3350 DSACKs received
    1 DSACKs for out of order packets received
    90851 connections reset due to unexpected data
    214 connections reset due to early user close
    352 connections aborted due to timeout
    TCPDSACKIgnoredNoUndo: 1571
    TCPSpuriousRTOs: 7
    TCPSackShifted: 94
    TCPSackMerged: 131
    TCPSackShiftFallback: 21183
    TCPTimeWaitOverflow: 1876775
    TCPRcvCoalesce: 15711184
    TCPOFOQueue: 3194
    TCPChallengeACK: 2337394
    TCPSYNChallenge: 13608
    TCPSpuriousRtxHostQueues: 1982796
IpExt:
    InBcastPkts: 46443933
    InOctets: 44312451521655
    OutOctets: 1915626725817
    InBcastOctets: 6827280595
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;喂，要是转载文章。麻烦贴一下出处 ykyi.net 采集爬虫把链接也抓走&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux系统级/进程级最多打开文件数,FD文件描述符数</title>
      <link>https://ykyi.net/?p=1551/</link>
      <pubDate>Thu, 22 Nov 2018 11:55:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=1551/</guid>
      <description>&lt;p&gt;如何增加Linux系统最大文件打开数目呢？&lt;/p&gt;
&lt;h3 id=&#34;查看系统最大可打开文件数&#34;&gt;查看系统最大可打开文件数&lt;/h3&gt;
&lt;p&gt;以下命令查看操作系统级最多可打开文件数,fd数目&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;$ cat /proc/sys/fs/file-max
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我用ubuntu 16输出:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;573738
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;怎么调整系统最大可打开文件数&#34;&gt;怎么调整系统最大可打开文件数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;# sysctl -w fs.file-max=1000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要用root用户执行以上命令，设最大为一百万。&lt;br&gt;
但在命令行上修改了这个配置，会在下一次操作系统重启后重置为以前的值。要一劳永逸的改变系统最大打开文件数，需要修改 /etc/sysctl.conf 文件。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;fs.file-max = 1000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在/etc/sysctl.conf文件中增加上述一行。&lt;/p&gt;
&lt;h3 id=&#34;ulimit命令查看调整进程级最大文件打开数&#34;&gt;ulimit命令查看/调整进程级最大文件打开数&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;$ ulimit -Sn
1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令查看一个ulimit的软极限值(soft limit)，本用户起的进程的最大文件打开数的限制。我的ubuntu 16显示进程最多开1024个fd。如果要提高每个进程可同时打开的文件数，需要更改这个值。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ ulimit -Sn 2048
bash: ulimit: open files: cannot modify limit: Invalid argument
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但我想把每个进程可同时打开的文件数增加到以前的两倍时，报错了。这是因为，软极限值(soft limit)不能够越过(Hard Limit)。我看了一下Hard limit，也是1024&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;&#34;&gt;$ ulimit -Hn
1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;那没办法罗，需要以root用户登录更改Hard Limit。&lt;/p&gt;
&lt;h3 id=&#34;怎么修改普通用户的硬极限hard-limit&#34;&gt;怎么修改普通用户的硬极限hard Limit&lt;/h3&gt;
&lt;p&gt;用root账户登录后，编辑 /etc/security/limits.conf文件，假如普通用户名是kamuszhou。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash &#34;&gt;kamuszhou hard nofile 10000
kamuszhou soft nofile 5000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上配置修改kamuszhou普通用户的最多打开文件数的hard limit为10000，soft limit为5000。&lt;br&gt;
对于ubuntu 16，如果使用图形桌面，还需要修改 /etc/systemd/system.conf 和 /etc/systemd/user.conf。&lt;br&gt;
加上这么一行：&lt;/p&gt;</description>
    </item>
    <item>
      <title>服务器端的tcp有大量TIME_WAIT怎么办</title>
      <link>https://ykyi.net/?p=1409/</link>
      <pubDate>Fri, 20 Oct 2017 06:03:06 +0000</pubDate>
      <guid>https://ykyi.net/?p=1409/</guid>
      <description>&lt;p&gt;公司的群里讨论tcp的TIME_WAIT的问题。TIME_WAIT这个状态可是面试时经常问的知识点啊。&lt;br&gt;
讨论的问题是：有一个服务器，它对外网提供服务，同时它作为客户端连接很多后端的其它服务器。这位同事连后端其它服务器时用了短tcp连接。结果出现了大量的tcp TIME_WAIT状态，吞吐量上不去，怎么办？&lt;/p&gt;
&lt;p&gt;先说结论：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果该服务器要处理外网IP的入流量，那最好的办法应该是用tcp长链接改造它与后端服务器的连接。如果用中间件，比如上zeromq那更省心了。&lt;/li&gt;
&lt;li&gt;如果不想做改动，并且在应用层确认已经交互已经完成，则可以用shutdown()直接发RST结束tcp会话，而不走正常的4次挥手。查阅shutdown系统调用的文档获知如何发RST。&lt;/li&gt;
&lt;li&gt;如果该服务器不需要处理处网IP请求的话，那么，启用port reuse 即打开net.ipv4.tcp_tw_reuse不会有太大问题(如果处理外网请求就有问题，和NAT相关，见&lt;a href=&#34;https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux&#34;&gt;https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux&lt;/a&gt;)，或者更好的，把/proc/sys/net/ipv4/tcp_fin_timeout改小，改成1或者2。让TIME_WAIT只保持很短的时间。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;首先，需要知道一个tcp会话由 src_ip, src_port, dest_ip, dest_port 四元组确定。&lt;br&gt;
我们公司的IDC环境中， 上述的服务器作为客户端再发起tcp连接联后端服务器，则 src_ip 固定了， dest_ip是后端服务器的ip, port是后端服务器监听端口。这样只有 src_port 是可变化的，但port只有16个bits还不能用well-known ports，这样就更少了。&lt;/p&gt;
&lt;p&gt;再说，主动关闭时，tcp连接需要进入TIME_WAIT状态，保持两倍MSL时长，是为了处理两种情况：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;让当前这个会话的迷路包在网路中消失。这样不会干扰到新建的会话。&lt;/li&gt;
&lt;li&gt;确保主动关闭方的FIN-ACK包，如果丢失的话，还能重发。&lt;br&gt;
1981年的TCP RFC上把MSL设成两分钟，https://tools.ietf.org/html/rfc793&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Maximum Segment Lifetime, the time a TCP segment can exist in&lt;br&gt;
the internetwork system. Arbitrarily defined to be 2 minutes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MSL设置这么长，因为以前的网络环境差啊。不过现在因为移动互联网，比较差的网络状态也是非常常见的。但RFC允许实现方减少MSL值。事实上linux的MSL写死在代码中为1分钟并且不可在运行期配置。&lt;br&gt;
如果tcp连接的双方都在性能高速稳定的内网中，这个MSL就太长了。&lt;/p&gt;
&lt;p&gt;调试时，还发现如果port用完了，connect的时候内核代码会用自旋锁忙等检查port资源。有linux内核开发基础的开发者都知道spin_lock的时候是不会让出cpu的，于是cpu全被spin_lock吃掉了。一直要等到有port被释放。再后来又发现，如果scoket没有设定SO_REUSEADDR选项，则connect()系统调用会返回EADDRINUSE。&lt;/p&gt;
&lt;p&gt;tcp的连接双方都是确定且长期的，用什么tcp短连接呢？？改造吧~~~&lt;/p&gt;</description>
    </item>
    <item>
      <title>用lftp为ftp服务器做镜像</title>
      <link>https://ykyi.net/?p=1401/</link>
      <pubDate>Wed, 27 Sep 2017 11:54:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=1401/</guid>
      <description>&lt;h3 id=&#34;用lftp为ftp服务器做镜像&#34;&gt;用lftp为ftp服务器做镜像&lt;/h3&gt;
&lt;p&gt;命令是这样的:&lt;/p&gt;
&lt;pre class=&#34;line-numbers prism-highlight&#34; data-start=&#34;1&#34;&gt;&lt;code class=&#34;language-null&#34;&gt;$ lftp -d -u user_name,password ftp_server_host -e &#34;mirror -c -e --parallel=5 / /path/to/mirror&#34;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解释一下这里的选项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;-d 调试模试，看到详细的输出&lt;/li&gt;
&lt;li&gt;-u 用户名和密码，用,隔开&lt;/li&gt;
&lt;li&gt;-e 让lftp执行lftp自有的一些命令&lt;/li&gt;
&lt;li&gt;mirror 执行做镜像命令&lt;/li&gt;
&lt;li&gt;-c continue a mirror job if possible 继续做镜像，如果可能的话。难道不用这个选项，做镜像的过程有可能被中断？&lt;/li&gt;
&lt;li&gt;-e 如果一个文件在ftp站点上没有，但在本机上有，则删除这个文件&lt;/li&gt;
&lt;li&gt;–parallel 并发数&lt;br&gt;
&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;br&gt;
mirror 命令还有一个 -R 参数，这样的话，会put文件到ftp服务器，效果和上例相反。&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title></title>
      <link>https://ykyi.net/?p=1327/</link>
      <pubDate>Tue, 17 Jan 2017 09:35:16 +0000</pubDate>
      <guid>https://ykyi.net/?p=1327/</guid>
      <description>&lt;h2 align=&#34;center&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;1. &lt;/span&gt;前言：
&lt;/h2&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt; &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt; &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;ZeroMq aka zmq&lt;/span&gt;是最知名的网络消息中间件之一。使有&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;的开源软件中最知名的莫过于&lt;span lang=&#34;EN-US&#34;&gt;Apache&lt;/span&gt;基金会下的&lt;span lang=&#34;EN-US&#34;&gt;Storm&lt;/span&gt;。我厂内部使用&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;的有即通的&lt;span lang=&#34;EN-US&#34;&gt;yaaf&lt;/span&gt;框架。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ZMQ&lt;/span&gt;社区在&lt;span lang=&#34;EN-US&#34;&gt;2013&lt;/span&gt;年&lt;span lang=&#34;EN-US&#34;&gt;9&lt;/span&gt;月发布了&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;。&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;最大的新功能即提供了一套安全机制，其中有&lt;span lang=&#34;EN-US&#34;&gt;IP&lt;/span&gt;黑白名单，用户名&lt;span lang=&#34;EN-US&#34;&gt;/&lt;/span&gt;密码鉴权，&lt;span lang=&#34;EN-US&#34;&gt;ECC(Elliptic Curve Cryptography)&lt;/span&gt;证书鉴权，以及通讯的加密&lt;span lang=&#34;EN-US&#34;&gt;(&lt;/span&gt;类似&lt;span lang=&#34;EN-US&#34;&gt;TSL)&lt;/span&gt;。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   &lt;/span&gt;本文主要介绍&lt;span lang=&#34;EN-US&#34;&gt;zmq4.0&lt;/span&gt;的安全机制。&lt;/p&gt;
&lt;h2 style=&#34;text-align: center;&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;2. &lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;的故事：
&lt;/h2&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   &lt;/span&gt;这里的&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;不是我厂历史上的电商事业群，而是椭圆曲线加密算法。&lt;span lang=&#34;EN-US&#34;&gt;ECC&lt;/span&gt;据说被&lt;span lang=&#34;EN-US&#34;&gt;NSA(&lt;/span&gt;美国安全局&lt;span lang=&#34;EN-US&#34;&gt;)&lt;/span&gt;操作，在算法中设置了后门。不过好在不是只有一种椭圆曲线，而是有无数种，不同的曲线有不同的优点和缺点，只是其中由&lt;span lang=&#34;EN-US&#34;&gt;NIST(&lt;/span&gt;美国标准和技术研究署&lt;span lang=&#34;EN-US&#34;&gt;)&lt;/span&gt;推荐的曲线被怀疑设置了后门。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ZMQ&lt;/span&gt;使用的椭圆曲线算法是&lt;span lang=&#34;EN-US&#34;&gt;&lt;a href=&#34;http://cr.yp.to/ecdh.html&#34;&gt;Curve25519&lt;/a&gt; ,&lt;/span&gt;它有开源实现而且没有专利保护。&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;用了长度为&lt;span lang=&#34;EN-US&#34;&gt;256bits&lt;/span&gt;的密钥，强度相当于&lt;span lang=&#34;EN-US&#34;&gt;RSA 3072&lt;/span&gt;比特的密钥长度。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;   ECDH(Elliptic Curve Diffie-Hellman)&lt;/span&gt;则是一个密钥协商协议。非常简单地讲，当&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;与&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;在一个不受信任的网络中通讯前，&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;先生成一对公私钥，并且&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;通过某个完全的渠道事先知道对方的公钥，然后&lt;span lang=&#34;EN-US&#34;&gt;A&lt;/span&gt;和&lt;span lang=&#34;EN-US&#34;&gt;B&lt;/span&gt;在握手阶段协商出一个双方公知的私钥供加密接下来的通讯。&lt;/p&gt;
&lt;p&gt;&lt;span lang=&#34;EN-US&#34;&gt;    &lt;/span&gt;可以理解成&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;设计了一个专门为自己定制的精简的&lt;span lang=&#34;EN-US&#34;&gt;TLS&lt;/span&gt;，更多的理论细节在&lt;span lang=&#34;EN-US&#34;&gt;&lt;a href=&#34;http://curvezmq.org/page:read-the-docs&#34;&gt;http://curvezmq.org/page:read-the-docs&lt;/a&gt;&lt;/span&gt;，&lt;/p&gt;
&lt;p&gt;作为一个码农，下面用代码介绍使用&lt;span lang=&#34;EN-US&#34;&gt;zmq4&lt;/span&gt;的Curve安全机制&lt;/p&gt;
&lt;h2 style=&#34;text-align: center;&#34;&gt;
  &lt;span lang=&#34;EN-US&#34;&gt;3. &lt;/span&gt;证书鉴权&lt;span lang=&#34;EN-US&#34;&gt;,&lt;/span&gt;通讯加密&lt;span lang=&#34;EN-US&#34;&gt;,&lt;/span&gt;&lt;span lang=&#34;EN-US&#34;&gt;IP &lt;/span&gt;白名单
&lt;/h2&gt;
&lt;p&gt;编译&lt;span lang=&#34;EN-US&#34;&gt;zmq4.x&lt;/span&gt;以后，会生成一个名叫&lt;span lang=&#34;EN-US&#34;&gt;curve_keygen&lt;/span&gt;的程序，用它可以生成&lt;span lang=&#34;EN-US&#34;&gt;zmq &lt;/span&gt;的证书。证书是一个一般的文本文件，如下是一个&lt;span lang=&#34;EN-US&#34;&gt;curve_keygen&lt;/span&gt;生成的&lt;span lang=&#34;EN-US&#34;&gt;zmq&lt;/span&gt;证书的例子。&lt;/p&gt;
&lt;div class=&#34;km_insert_code&#34;&gt;
  &lt;pre class=&#34;brush:other&#34;&gt;#   ****  Generated on 2017-01-02 14:24:20 by CZMQ  ****
#   ZeroMQ CURVE **Secret** Certificate
#   DO NOT PROVIDE THIS FILE TO OTHER USERS nor change its permissions.
&lt;p&gt;metadata
    email = &amp;ldquo;&lt;a href=&#34;mailto:kamuszhou@tencent.com&#34;&gt;kamuszhou@tencent.com&lt;/a&gt;&amp;rdquo;
curve
    public-key = &amp;ldquo;!Upjrn]2Dk)jQkYREsceBnpgoIL7koE{CVnV1j4D&amp;rdquo;
    secret-key = &amp;ldquo;ZPT#=l/#Rtg:TeLbofh:uPi7#/w(GDZq[0^qPZA1&amp;rdquo;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;
  &amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>原来比特位也有大小端endinness.字节序和比特序的故事</title>
      <link>https://ykyi.net/?p=1318/</link>
      <pubDate>Tue, 13 Sep 2016 11:52:46 +0000</pubDate>
      <guid>https://ykyi.net/?p=1318/</guid>
      <description>&lt;pre&gt;我一直以为&lt;strong&gt;大小端endianness&lt;/strong&gt;只针对字节，不针对比特位。
我一直以为全世界所有的cpu解释bit序都是一样的。

昨天才知道endianness也针对bit。
于是就想不明白了。
因为观察到用 htonl 函数转换endianness后，bit位没有变化，只有字节顺序改了呀。&lt;/pre&gt;
&lt;p&gt;于是google呀，找到这篇好文：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://www.linuxjournal.com/article/6788?page=0,0&#34;&gt;http://www.linuxjournal.com/article/6788?page=0,0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;“&lt;a href=&#34;http://www.linuxjournal.com/article/6788?page=0,0&#34;&gt;Byte and Bit Order Dissection&lt;/a&gt;”(字节序和比特序深入剖析)&lt;/p&gt;
&lt;p&gt;看了这篇文章，才知道 bit序的翻转是由硬件完成的。原来以前这方面很多概念都没理解对。&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP2简单教程</title>
      <link>https://ykyi.net/?p=1282/</link>
      <pubDate>Fri, 03 Apr 2015 08:22:39 +0000</pubDate>
      <guid>https://ykyi.net/?p=1282/</guid>
      <description>&lt;p&gt;译自：&lt;a href=&#34;http://qnimate.com/post-series/http2-complete-tutorial/&#34;&gt;http://qnimate.com/post-series/http2-complete-tutorial/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;HTTP1.1是在1999年的时候被引入业界的。从当时到现在，WEB已经发生了相当大的变化。很多人开始用移动设备上网，有些移动环境下网络质量非常不稳定。另外，WEB页面的内容也相当的丰富了。这些都负面影响了WEB页面的加载时间。因此，需要一个新的协议来加速WEB的加载。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;和&lt;/strong&gt;&lt;/strong&gt;SPDY****的区别：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SPDY是谷歌于2009年创造的协议，旨在WEB延迟以及增强安全性。&lt;/p&gt;
&lt;p&gt;HTTP/2是SPDY的一个克隆。谷歌已经停止了继续开发SPDY，并且把工作转移到了HTTP/2上来。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****的目标：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;减少加载延时。&lt;/li&gt;
&lt;li&gt;减少TCP连接数。&lt;/li&gt;
&lt;li&gt;增强的网络安全。&lt;/li&gt;
&lt;li&gt;保持和HTTP/1.1的兼容。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****的功能：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;多路复用Multiplexing：很多个异步的HTTP请求只使用一个TCP的连接。&lt;/li&gt;
&lt;li&gt;服务端PUSH：对于一个请求可能有多个回复。&lt;/li&gt;
&lt;li&gt;头部压缩：压缩头部(headers)。&lt;/li&gt;
&lt;li&gt;请求分级：对同一个域名的请求可作优先级分级。&lt;/li&gt;
&lt;li&gt;二进制协议：HTTP/2是一个二进制协议，而HTTP/1.1是一个文本协议。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;解决了&lt;/strong&gt;&lt;/strong&gt;HTTP/1.1****的哪些问题：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HTTP管道(HTTP pipelining)：一些HTTP1.1客户端使用了HTTP管道技术来减少TCP连接数。HTTP管道指的是多个HTTP请求被发往同一个TCP连接，而不等待前一个请求的回复。但是服务端发送回复时的顺序和收到的请求的顺序一样。因此，造成了HOL阻塞问题(head-of-line blocking)。HOL Blocking简单地说是一个回复的延迟会使得排在它后面的回复都会延迟。HTTP/2透过引用多路复用(Multiplexing)解决了这个问题。多个HTTP请求和多个HTTP回复都使用同一个TCP连续，而且HTTP回复的顺序不需要保持HTTP请求到达的顺序。&lt;/li&gt;
&lt;li&gt;同一个域名的多个TCP连接：在使用HTTP/1.1时，需要对同一个域名起多个TCP连接来增加吞吐量。而使用HTTP/2时，对于每个域名，只充许有一个TCP连接（only one TCP connection per domain is allowed）。所有的请求和回复都通过唯一的一个TCP连接进行。&lt;/li&gt;
&lt;li&gt;TCP连接的关闭时间：使用HTTP1.1时，一个TCP连接在请求完成时立刻被关闭。但对于HTTP/2，TCP连接能存活相当成地一段时间。&lt;/li&gt;
&lt;li&gt;头部压缩：HTTP/1.1是没有头部压缩的，但HTTP/2引入头部压缩进一步的减少了延时。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2&lt;strong&gt;&lt;strong&gt;如何兼容&lt;/strong&gt;&lt;/strong&gt;HTT/1?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2客户端在不确定对方服务器是否支持HTTP/2时，会用HTTP/1协议向服务器发送请求时带上Upgrade: HTTP/2.0这个头部。如果对方服务器支持HTTP/2，就会回复HTTP1.1 101，表示切换协议(Switching Protocols status)。而对于老旧的服务器则简单地返回HTTP/1.1的状态。&lt;/p&gt;
&lt;p&gt;HTTP/2客户端可以记下哪些服务器支持HTTP/2，这样，下次就可以直接发起HTTP/2请求，而不必再经过一个询问和回复(Upgrade Round Trip).&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****中的多路复用是怎么回事？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2使用多路复用，多个请求和回复全异步的通过同一个TCP连接收发。&lt;/p&gt;
&lt;p&gt;HTTP/2是一个二进制的协议。每一个请求和回复都被分配了一个流标志(Stream ID)，而且请求和回复被切成了很多帧(Frame)，属于同一个请求或回复帧的Stream ID相同。因为有了这个Stream ID和Frame的机制，请求和回复可以在服务器和客户程序两端同时全异步的发送。因此，HTTP2没有了Head-of-line Blocking的问题。&lt;/p&gt;
&lt;p&gt;每一个Stream还可以被赋于一个优先级，服务器可以分配更多的系统资源处理高优级的Stream。&lt;/p&gt;
&lt;p&gt;HTTP/2还有一个传输层级别的流控。它协商了客户程序和服务器两端最多使用多少个Stream,服务器能处理的最大尺寸的Stream以及整个连接最多处理多少字节，以及数据被发送的速率。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;HTTP/2中的服务器推送(Server Push)和承诺(Promise)&lt;/p&gt;
&lt;p&gt;当服务器“感觉”到客户程序需要更多的资源时，就会给客户程序发送一个Promise Stream ，提醒客户程序需要什么资源。这些stream比一般的stream的优先级要高。&lt;/p&gt;
&lt;p&gt;这项技术在加载网页时非常用户，因为网页的大量css和javascrpit可能通过这种方式发送。而HTTP/1的作法是把css和js都combine到一起。&lt;/p&gt;
&lt;p&gt;服务器发送Promise Stream时提醒的资源遵守同源策略(same origin policy)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP/2****中的头部压缩：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;HTTP/2的头部压缩和HTTP/1.1中早有的用gzip压缩Body不一样。使用HTTP/2时，在客户程序和服务器两端，都会保存一张表，记录了收到过的头部。它们在发送HTTP时不会重复发送一样的头部，当再次发送相同的头部时，只会发送该头部对应的表的索引号。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 12px; line-height: 22.8000011444092px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux 如何知道有哪些硬件，该装哪个驱动</title>
      <link>https://ykyi.net/?p=1255/</link>
      <pubDate>Wed, 23 Jul 2014 03:12:12 +0000</pubDate>
      <guid>https://ykyi.net/?p=1255/</guid>
      <description>&lt;p&gt;Linux 如何知道有哪些硬件，该装哪个驱动&lt;/p&gt;
&lt;p&gt;公司明文不准安装虚拟机了，被查到就是死罪。于是我在自己的笔记本上安装了Debian Linux。&lt;/p&gt;
&lt;p&gt;结果无线网卡识别不了~~&lt;/p&gt;
&lt;p&gt;次奥~&lt;/p&gt;
&lt;p&gt;怎么破呢？&lt;/p&gt;
&lt;p&gt;这么破:&lt;/p&gt;
&lt;pre style=&#34;margin-top: 0px; margin-bottom: 10px; padding: 5px; border: 0px; font-size: 13px; vertical-align: baseline; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, serif; background-color: rgb(238, 238, 238); word-wrap: normal; line-height: 20px;&#34;&gt;&lt;code style=&#34;margin: 0px; padding: 0px; border: 0px; font-size: 13px; vertical-align: baseline; font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, serif; color: rgb(34, 34, 34); white-space: inherit;&#34;&gt;# lspci
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&#34;margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15.333333015441895px; vertical-align: baseline; clear: both; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; line-height: 20px;&#34;&gt;
  该命令列出了所有PCI总线上的硬件设备，稍微看看就能看到自己的无线网卡了。
&lt;/p&gt;</description>
    </item>
    <item>
      <title>什么是0MQ或ØMQ，或ZeroMQ</title>
      <link>https://ykyi.net/?p=1170/</link>
      <pubDate>Sat, 18 Jan 2014 10:39:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=1170/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;line-height: 1.6em;&#34;&gt;ØMQ或者拼写成ZeroMQ,0MQ，是一个高性能异步消息队列库，旨在在分布式可扩展的并行程序中使用。它提供了一个消息队列，但不像面向消息的中间件，即使没有特定的消息经纪人(Message Broker)，0MQ也能正常工作。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;这个库在TCP的基础上开发，但能获得比TCP更高的性能，更不用说它提供了各种安全机制和分布式易扩展的特性。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;0MQ的API和传统的socket很像。OMQ中的socket描述了一个,多个终端之间的多对多的连接。0MQ还有一个消息模式的概念。基本的0MQ消息模式有：&lt;/p&gt;
&lt;p&gt;Request-reply:&lt;/p&gt;
&lt;p&gt;用来连接一组客户端和一组服务。这个模式是一个远程过程调用RPC，和多任务分发模式。&lt;/p&gt;
&lt;p&gt;Publish-subscribe:&lt;/p&gt;
&lt;p&gt;用来连接一组发行端和一组接收端。这是一个数据分发模式。&lt;/p&gt;
&lt;p&gt;Push-Pull(Pipeline)&lt;/p&gt;
&lt;p&gt;用扇入/扇出模式连接很多结点，通常要分好几个步骤。这是一个多任务并行分布和收集的模式。&lt;/p&gt;
&lt;p&gt;Exclusive Pair:&lt;/p&gt;
&lt;p&gt;用排它模式连组两个socket。这其实是一个为特殊需求准备的高级底层模式。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;每一种模式定义了一个对应的网络拓扑。Request-reply模式定义了所谓的”服务总线”，publish-subscribe定义了数据分发树，push-pull定义了并行管道。这样模式都被精心设计，使他们可以在互联网上被无限扩展。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;不想译了,。更多内容见wikipedia。&lt;a href=&#34;mailto:kamuszhou@qq.com&#34; style=&#34;font-size: 13px;&#34;&gt;&lt;a href=&#34;mailto:kamuszhou@qq.com&#34;&gt;kamuszhou@qq.com&lt;/a&gt;&lt;/a&gt;&lt;span style=&#34;font-size: 13px;&#34;&gt; 腾讯视频广告&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP中的HEAD方法是什么</title>
      <link>https://ykyi.net/?p=1122/</link>
      <pubDate>Wed, 08 Jan 2014 02:29:55 +0000</pubDate>
      <guid>https://ykyi.net/?p=1122/</guid>
      <description>&lt;p&gt;HTTP中的HEAD方法和GET方法是一样的，除了服务器在响应HEAD方法时不充许活加消息体(message body).服务器用来回复HEAD的响应信息中，在HTTP头部中的元信息需要跟回复GET时一样。这样，一个客户就可以通过HEAD来得到某资源的源信息，而不需要把整个资源都传输一次。&lt;/p&gt;
&lt;p&gt;HEAD方法通常被用来测试超链接的可达，和资源是否已经更新。&lt;/p&gt;
&lt;p&gt;HEAD方法的主要应用场景是检索资源的元信息meta infomation。用getResponseHeaders()函数可以得到HTTP的头部~&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
    <item>
      <title>昨天解决了tcpcopy的一个小却很重要的bug.</title>
      <link>https://ykyi.net/?p=1041/</link>
      <pubDate>Wed, 20 Nov 2013 02:48:59 +0000</pubDate>
      <guid>https://ykyi.net/?p=1041/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;tcpcopy的基础函数有个bug，流量比较大的时候，内核buffer满了。send系统调用发不完用户缓冲中的数据才会出现。然后加入了tcpcopy的QQ群，和作者稍稍讨论了一点时间。问了关于写论文和tc_session.c过于复杂的问题。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:16px;&#34;&gt;(wangb) 10:00:55 &lt;br /&gt; &lt;a href=&#34;https://github.com//tcpcopy/pull/162&#34;&gt;https://github.com//tcpcopy/pull/162&lt;/a&gt;&lt;br /&gt; (wangb) 10:01:04 &lt;br /&gt; The bug arises when send system call returns with part of data transfered&lt;br /&gt; and part of data still need to be sent again.&lt;br /&gt; (wangb) 10:01:13 &lt;br /&gt; 常见于压力比较大的场合&lt;br /&gt; (wangb) 10:02:14 &lt;br /&gt; 当然如果系统参数设置好的话，这样的情况不常见。这也是为啥我这边无法重现的原因所在&lt;br /&gt; (wangb) 10:02:46 &lt;br /&gt; 当然昨天在开发gryphon，貌似遇到过一次&lt;br /&gt; (wangb) 10:03:06 &lt;br /&gt; gryphon给的压力，有时候真不是一般快和大&lt;br /&gt; siu1ooooooo(16236914) 10:03:14 &lt;br /&gt; 我在tcpcopy上作二次开发。碰到了个bug，最后追踪到了 tc_socket_send函数。&lt;br /&gt; siu1ooooooo(16236914) 10:03:52 &lt;br /&gt; 流量比较大的时候，内核buffer满了。send系统调用发不完用户缓冲中的数据才会出现。&lt;br /&gt; siu1ooooooo(16236914) 10:05:21 &lt;br /&gt; 希望能贡献更多代码的。。但是tc_session.c这个模拟tcp状态机的代码太难看懂了。&lt;br /&gt; (wangb) 10:05:49 &lt;br /&gt; 有些bug，程序员自身很难发现，往往需要依赖于用户的反馈，当然有上面的bug提出，就更好了&lt;br /&gt; tc_session.c这个模拟tcp状态机，其实不仅模拟tcp状态机，而为复杂的是模拟上层应用交互&lt;br /&gt; 光模拟tcp状态机，是远远不够的&lt;br /&gt; siu1ooooooo(16236914) 10:07:27 &lt;br /&gt; 有个想法， 把TCP的11个标准状态加入到tc_session中。可不可以做的。.&lt;br /&gt; (wangb) 10:09:13 &lt;br /&gt; 数据是死的，但测试服务器是活的。应该可以吧，但加入可能会更复杂。tc_session.c这个会进一步改进的，代码需简化和功能需独立，使其易懂&lt;br /&gt; siu1ooooooo(16236914) 10:09:31 &lt;br /&gt; 🙂&lt;br /&gt; (wangb) 10:10:33 &lt;br /&gt; 2010～2012.5月，初步探索阶段；2012.5～2014.5，为进一步探索阶段 2014.5～以后，进一步优化&lt;br /&gt; 因为tcpcopy刚开始，开发人员是无法知道复杂的互联网的各种应用的特性的，只有积累到一定程度，才能进一步优化。与其说是开发，不如说是探索&lt;br /&gt; siu1ooooooo(16236914) 10:12:10 &lt;br /&gt; 期待工程paper  &lt;br /&gt; siu1ooooooo(16236914) 10:12:43 &lt;br /&gt; tcpcopy稳定到了一个版本。先别加功能了。写paper吧  &lt;br /&gt; siu1ooooooo(16236914) 10:13:01 &lt;br /&gt; 投中EI应该问题不大。&lt;br /&gt; siu1ooooooo(16236914) 10:13:55 &lt;br /&gt; 中了paper，贡献者会迅速增多。&lt;br /&gt; wangb() 10:15:43 &lt;br /&gt; 其实写过sigcomm论文，但被拒，说应该投USENIX ATC&lt;br /&gt; wangb() 10:16:18 &lt;br /&gt; I don&amp;rsquo;t think that the research contribution of the paper is a good match for Sigcomm. Perhaps it would be a better match for &lt;br /&gt; a more practice-oriented conference like USENIX ATC. &lt;br /&gt; siu1ooooooo(16236914) 10:16:50 &lt;br /&gt; 后来呢&lt;br /&gt; wangb() 10:17:05 &lt;br /&gt; 确实，tcpcopy是基于实践的，从实践中摸索爬行的。后来我就先不写论文了&lt;br /&gt; siu1ooooooo(16236914) 10:17:22 &lt;br /&gt; 嗯。这是个工程实践性很强的探索啊&lt;br /&gt; wangb() 10:17:27 &lt;br /&gt; 要写论文，必须要有条件&lt;br /&gt; siu1ooooooo(16236914) 10:17:45 &lt;br /&gt; 喔。&lt;br /&gt; wangb() 10:18:06 &lt;br /&gt; 从交换机或者其它设备。镜像过来，这样测试系统和在线系统就没有关联，这样的论文是能够中USENIX ATC&lt;br /&gt; 的&lt;br /&gt; wangb() 10:19:13 &lt;br /&gt; tcpcopy最高端的应用，就是在交换机，利用分光镜或者其它镜像设备，利用高性能硬件，把用户的请求数据包复制给测试系统，可惜我没有这样的条件&lt;br /&gt; wangb() 10:19:38 &lt;br /&gt; 要是有这样的条件，我肯定要写论文了&lt;br /&gt; siu1ooooooo(16236914) 10:19:55 &lt;br /&gt; 呃。。没怎么看懂  &lt;br /&gt; siu1ooooooo(16236914) 10:21:49 &lt;br /&gt; 是说复制的流量要非常非常大才能中论文么&lt;br /&gt; siu1ooooooo(16236914) 10:21:59 &lt;br /&gt; 而非常大的流量需求硬件支持&lt;br /&gt; wangb() 10:22:02 &lt;br /&gt; twitter梦想的测试环境，其实完全可以用我们的tcpcopy来实现。交换机上面不是有来来往往的数据包吗？在那上面把请求数据包镜像到测试系统，测试系统搭一个跟在线类似的完整系统，这样测试系统跟在线系统承受类似的压力&lt;br /&gt; wangb() 10:22:17 &lt;br /&gt; 高端大气，才能中论文&lt;br /&gt; wangb() 10:22:48 &lt;br /&gt; 屌丝环境，写论文，还不被批啊&lt;br /&gt; siu1ooooooo(16236914) 10:23:14 &lt;br /&gt; 呃。是 。。。明白了。。想起以前学校的事情，懂了。&lt;br /&gt; wangb() 10:24:38 &lt;br /&gt; 总之，tcpcopy值得你去研究，期望有更多接班人把思想传承下去，代码可以推掉重来&lt;br /&gt; wangb() 10:25:10 &lt;br /&gt; 只要tcp协议还存在，这个思想，应该是最先进的，无法再先进了&lt;br /&gt; siu1ooooooo(16236914) 10:26:11 &lt;br /&gt; 需要好多的开发时间啊。..嗯。先上班了啊。多谢wangbin….&lt;br /&gt; wangb() 10:27:16 &lt;br /&gt; 慢慢来，这方面反正国外没有人做&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>tcpcopy在视频广告组的二次开发</title>
      <link>https://ykyi.net/?p=1022/</link>
      <pubDate>Wed, 16 Oct 2013 09:01:05 +0000</pubDate>
      <guid>https://ykyi.net/?p=1022/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;流量筛选中的 “只导入某频道的流量”功能已经实现了。&lt;/p&gt;
&lt;p&gt;技术层面上，实际上是通过指定正则式的方法匹配HTTP请求中的GET方法中的URL来达到过滤的目的。&lt;/p&gt;
&lt;p&gt;所以，也可以用ty，ad_type, pf, coverid, oadid, v，plugin等出现在GET方法中的参数编写正则式来过滤流量。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;流量筛选中的“地域纬度筛选”暂时没有实现。&lt;/p&gt;
&lt;p&gt;因为地域纬度的信息不是以参数形式出现在GET方法的URL中，需要通过IP地址或者cookie的中QQ号信息来判断。&lt;/p&gt;
&lt;p&gt;还没最终决定是否实现这个功能。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;tcpcopy官方版本主要的应用场景是复制实时流量。所以部署的时候至少两台机器，一台线上机，另一台测试用机。为了方便压力测试，还引入了至少三台机器的高级模式。&lt;/p&gt;
&lt;p&gt;部署起来比较麻烦。&lt;/p&gt;
&lt;p&gt;如果“视频CPM广告的模拟投放，以及订单效果预估“只是从磁盘中读入以往的流量，针对这种场景，可以探索tcpcopy的单机离线模式，做到方便部署和使用。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;部分同学有一个误解.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;ldquo;将线上的实际访问流量，复制一份保存到本地服务器，用于后续使用&amp;rdquo;&lt;/p&gt;
&lt;p&gt;目前，tcpcopy的官方的版本没有把流量保存下来的功能，保存流量这个目前是用tcpdump的-w选项来做的。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;另外，技术上，tcpdump只能在IP层和TCP层指定过滤条件，不能用业务的逻辑过滤流量。第1点提到的流量筛选工作在tcpcopy读入实时流量时，或者从tcpdump存下的文件中读入流量时，在应用层指定过滤条件。&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;color: rgb(0, 0, 0); font-family: Verdana, Geneva, sans-serif; font-size: 16px; line-height: 22px;&#34;&gt;copyright ykyi.net&lt;/span&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux抓包技术简介</title>
      <link>https://ykyi.net/?p=1006/</link>
      <pubDate>Tue, 10 Sep 2013 05:05:03 +0000</pubDate>
      <guid>https://ykyi.net/?p=1006/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    Linux抓包技术简介
  &lt;/p&gt;
  &lt;p&gt;
    Author: zausiu@gmail.com
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;简介
  &lt;/p&gt;
  &lt;p&gt;
    大多数应用常景下，我们在IP层上用AF_INET或AF_INET6作为socket的第一个参数，SOCK_STREAM或SOCK_DGRAM作为socket的第二个参数创建最为常见的IPv4或IPv6的TCP或UDP套接字。这样的套接字满足了绝大多数网络应用常景。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    本文简单介绍三种Linux平台下抓包，截获包的技术。它们提供一些更酷的功能。每种技术的水都很深，作者个人水平有限，按照自己的理解做一般的介绍。仅仅旨在起到科谱的作用。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;RAW&amp;nbsp;SOCKET
  &lt;/p&gt;
  &lt;p&gt;
    参数SOCK_RAW可以作为socket函数的第二个参数传入，这样创建的套接字称为原始套接字。设置Socket的第一个参数可以让指定原始套接字开在数据链路层上或者网络层。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    下面的语句创建在数据链路层上的原始socket。
  &lt;/p&gt;
  &lt;p&gt;
    Socket(AF_PACKET,&amp;nbsp;SOCK_RAW,&amp;nbsp;htons(ETH_P_ALL));&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    在负载不大的情况下，读这个socket可以拿到本机收到的所有数据包。写入这个socket需要程序员负责填充各种包头的数据。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    Socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;xxxxx协议号)；
  &lt;/p&gt;
  &lt;p&gt;
    在IP层上创建IPv4的RAW&amp;nbsp;socket，可以拿到各种经由IPv4的数据包，比如ICMP包，IGMP包等。Steven的&lt;Unix网络编程&gt;第三版第28.4节，第二段：&amp;ldquo;系统收到的UDP包和TCP包不会传给原始套接字&amp;rdquo;。但读tcpcopy的源代码时，确实用了原始套接字在网络层读UDP和TCP包。难道书上写的过时了。见代码，来自tcpcopy：
  &lt;/p&gt;
  &lt;p&gt;
    #if&amp;nbsp;(TCPCOPY_UDP)
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fd&amp;nbsp;=&amp;nbsp;socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;IPPROTO_UDP);
  &lt;/p&gt;
  &lt;p&gt;
    #else
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fd&amp;nbsp;=&amp;nbsp;socket(AF_INET,&amp;nbsp;SOCK_RAW,&amp;nbsp;IPPROTO_TCP);
  &lt;/p&gt;
  &lt;p&gt;
    #endif
  &lt;/p&gt;
  &lt;p&gt;
    另外，在IP层上创建的原始套接字有一个选项：IP_HDRINCL，它被开启时，则内核帮助填充IP包头。Linux默认没有开启这个选项。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;NF_Queue
  &lt;/p&gt;
  &lt;p&gt;
    NF_Queue是用户空间的一个库，需要内核模块NETFILTER_NETLINK_QUEUE的支持。官方网址：&lt;a href=&#34;http://www.netfilter.org/&#34;&gt;http://www.netfilter.org&lt;/a&gt;。通过这个库可以在数据包被发往用户空间处理前截获数据包，或者在数据包被发往网卡前截获数据库。截获后，可以修改数据包的内容，并决定是否丢充这个数据库。
  &lt;/p&gt;
  &lt;p&gt;
    NF_Queue可以用来编写防火墙等安全软件。
  &lt;/p&gt;
  &lt;p&gt;
    Tcpcopy使用NF_Queue丢弃测试中的程序回复给真实客户程序的数据包，使测试中程序回复的报文不影响真实客户程序。
  &lt;/p&gt;
  &lt;p&gt;
    另一个提供类似功能的库是IP_Queue，它已经被废弃。NF_Queue可以完全取代IP_Queue。我们用的tlinux，内核中built-in了NF_Queue模块。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;libpcap
  &lt;/p&gt;
  &lt;p&gt;
    大名鼎鼎的Libpcap是一个古老的可以工作在所有Unix-like平台上的抓包库，比linux年纪更大。Tcpdump的广泛使用让libpcap成为事实上的行业标准。它可以很方便的编写抓取数据链路层上的数据包，并可以设置过滤条件在内核级别只复制关心的数据包，而数据链路层上的原始套接字会尽最大努力复制所有的包，所以libpcap的工作效率高。而且，pcap使用方便。下面是一个很简单的使用pcap抓到发往80端口的tcp包并打印源IP，目的IP，和目的端口号的程序。非常短，很容易看，起到介绍libpcap的作用。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;int&amp;nbsp;main(int&amp;nbsp;argc,&amp;nbsp;char&amp;nbsp;*argv[])
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    pcap_t&amp;nbsp;*handle; //&amp;nbsp;pcap用的句柄，和其它各种句柄一样。
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;*dev; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;网络接口名，如eth0,&amp;nbsp;eth1,&amp;nbsp;tunl0&amp;nbsp;之类
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;errbuf[PCAP_ERRBUF_SIZE]; //&amp;nbsp;存描述出错原因的缓冲
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;bpf_program&amp;nbsp;fp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap用来过滤数据包用
  &lt;/p&gt;
  &lt;p&gt;
    char&amp;nbsp;filter_exp[]&amp;nbsp;=&amp;nbsp;&#34;tcp&amp;nbsp;and&amp;nbsp;dst&amp;nbsp;port&amp;nbsp;80&#34;;&amp;nbsp;//&amp;nbsp;过滤字符串，和tcpdump的写法一样
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;pcap_pkthdr&amp;nbsp;header;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap自己用的包头
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*packet; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;pcap包头后的数据，即抓到的数据
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;len_of_iphdr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;ip头的长度
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;in_addr&amp;nbsp;src_ip;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;源IP地址
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;in_addr&amp;nbsp;dst_ip;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;目的IP
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*ip_hdr_addr; //&amp;nbsp;IP头的首地址
  &lt;/p&gt;
  &lt;p&gt;
    const&amp;nbsp;u_char&amp;nbsp;*tcp_hdr_addr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;tcp头的首地址
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;tcphdr&amp;nbsp;*tcp_hdr;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;tcp头结构体
  &lt;/p&gt;
  &lt;p&gt;
    u_short&amp;nbsp;dst_port;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;目的端口
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;如果命令行指定网卡名
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(argv[1])
  &lt;/p&gt;
  &lt;p&gt;
    dev&amp;nbsp;=&amp;nbsp;argv[1];&amp;nbsp;//就用指定的网卡
  &lt;/p&gt;
  &lt;p&gt;
    else
  &lt;/p&gt;
  &lt;p&gt;
    dev&amp;nbsp;=&amp;nbsp;&#34;eth0&#34;;&amp;nbsp;//否则用eth0
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;用pcap打开这个网卡
  &lt;/p&gt;
  &lt;p&gt;
    handle&amp;nbsp;=&amp;nbsp;pcap_open_live(dev,&amp;nbsp;BUFSIZ,&amp;nbsp;0,&amp;nbsp;1000,&amp;nbsp;errbuf);
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(handle&amp;nbsp;==&amp;nbsp;NULL)&amp;nbsp;{&amp;nbsp;&amp;nbsp;//&amp;nbsp;打开网卡出错
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;open&amp;nbsp;device&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;dev,&amp;nbsp;errbuf);
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;编译过滤文件
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(pcap_compile(handle,&amp;nbsp;&amp;fp,&amp;nbsp;filter_exp,&amp;nbsp;0,&amp;nbsp;net)&amp;nbsp;==&amp;nbsp;-1)&amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;parse&amp;nbsp;filter&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;filter_exp,&amp;nbsp;pcap_geterr(handle));
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;设置过滤条件
  &lt;/p&gt;
  &lt;p&gt;
    if&amp;nbsp;(pcap_setfilter(handle,&amp;nbsp;&amp;fp)&amp;nbsp;==&amp;nbsp;-1)&amp;nbsp;{
  &lt;/p&gt;
  &lt;p&gt;
    fprintf(stderr,&amp;nbsp;&#34;Couldn&#39;t&amp;nbsp;install&amp;nbsp;filter&amp;nbsp;%s:&amp;nbsp;%s\n&#34;,&amp;nbsp;filter_exp,&amp;nbsp;pcap_geterr(handle));
  &lt;/p&gt;
  &lt;p&gt;
    return(2);
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;抓包
  &lt;/p&gt;
  &lt;p&gt;
    packet&amp;nbsp;=&amp;nbsp;pcap_next(handle,&amp;nbsp;&amp;header);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;至此packet指向抓到的一个目标端口号是80的数据链路层的包
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;它的包结构是&amp;nbsp;14字节以太网包头&amp;nbsp;+&amp;nbsp;可变IPv4包头&amp;nbsp;+&amp;nbsp;TCP包头
  &lt;/p&gt;
  &lt;p&gt;
    ip_hdr_addr&amp;nbsp;=&amp;nbsp;(u_char*)(packet&amp;nbsp;+&amp;nbsp;sizeof(struct&amp;nbsp;ethernet_hdr));
  &lt;/p&gt;
  &lt;p&gt;
    src_ip.s_addr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;saddr;
  &lt;/p&gt;
  &lt;p&gt;
    dst_ip.s_addr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;daddr;
  &lt;/p&gt;
  &lt;p&gt;
    len_of_iphdr&amp;nbsp;=&amp;nbsp;((struct&amp;nbsp;iphdr*)ip_hdr_addr)-&gt;ihl&amp;nbsp;*&amp;nbsp;4;
  &lt;/p&gt;
  &lt;p&gt;
    tcp_hdr_addr&amp;nbsp;=&amp;nbsp;ip_hdr_addr&amp;nbsp;+&amp;nbsp;len_of_iphdr;
  &lt;/p&gt;
  &lt;p&gt;
    tcp_hdr&amp;nbsp;=&amp;nbsp;(struct&amp;nbsp;tcphdr*)tcp_hdr_addr;
  &lt;/p&gt;
  &lt;p&gt;
    dst_port&amp;nbsp;=&amp;nbsp;tcp_hdr-&gt;dest;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    //&amp;nbsp;经过上面的各种指针偏移，下面打印源IP和目标IP和目标端口.
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;src&amp;nbsp;addr&amp;nbsp;%s\n&#34;,&amp;nbsp;inet_ntoa(src_ip));
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;dst&amp;nbsp;addr&amp;nbsp;%s\n&#34;,&amp;nbsp;inet_ntoa(dst_ip));
  &lt;/p&gt;
  &lt;p&gt;
    printf(&#34;dst_port&amp;nbsp;%d\n&#34;,&amp;nbsp;ntohs(dst_port));
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    /*&amp;nbsp;And&amp;nbsp;close&amp;nbsp;the&amp;nbsp;session&amp;nbsp;*/
  &lt;/p&gt;
  &lt;p&gt;
    pcap_close(handle);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    return(0);
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;}
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;总结
  &lt;/p&gt;
  &lt;p&gt;
    本文只是一个非常简单的介绍。如需要进阶学习，Stevens的网络编译有更详细地关于Raw&amp;nbsp;Socket的内容，研究NF_Queue技术则需要读源代码和收集散在社区各个角落的资料了，而讲libpcap有两篇很好的文章：
  &lt;/p&gt;
  &lt;p&gt;
    &#34;&lt;a href=&#34;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&#34;&gt;Programming&amp;nbsp;with&amp;nbsp;Libpcap&amp;nbsp;&amp;ndash;&amp;nbsp;Sniffing&amp;nbsp;the&amp;nbsp;network&amp;nbsp;from&amp;nbsp;our&amp;nbsp;own&amp;nbsp;application&amp;nbsp;&lt;/a&gt;&#34;用Libpcap编程，在我们的程序中嗅探网络。非常漂亮的pdf文档。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&#34;&gt;http://recursos.aldabaknocking.com/libpcapHakin9LuisMartinGarcia.pdf&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://yuba.stanford.edu/~casado/pcap/section1.html&#34;&gt;The&amp;nbsp;Sniffer&amp;rsquo;s&amp;nbsp;Guide&amp;nbsp;to&amp;nbsp;Raw&amp;nbsp;Traffic&lt;/a&gt;&amp;nbsp;嗅探器教程。斯坦福大学的Geek于大概2001年写的。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;a href=&#34;http://yuba.stanford.edu/~casado/pcap/section1.html&#34;&gt;http://yuba.stanford.edu/~casado/pcap/section1.html&lt;/a&gt;
  &lt;/p&gt;
  &lt;p&gt;
    copyright ykyi.net
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>epoll学习报告</title>
      <link>https://ykyi.net/?p=976/</link>
      <pubDate>Wed, 07 Aug 2013 12:01:31 +0000</pubDate>
      <guid>https://ykyi.net/?p=976/</guid>
      <description>&lt;div&gt;
  &lt;p&gt;
    &amp;nbsp;epoll学习报告
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kamuszhou&amp;nbsp;周霄&amp;nbsp;Jul/26/2013
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    这几天通读了内核中对epoll&amp;nbsp;I/O模型的实现代码，结合网络上很多介绍epoll的文章，对epoll的实现原理已经很熟悉，下面谈谈我的几点体会。下文引用的内核代码来自3.9.6版本的内核，见URL：&lt;a href=&#34;http://lxr.oss.org.cn/source/fs/eventpoll.c&#34;&gt;http://lxr.oss.org.cn/source/fs/eventpoll.c&lt;/a&gt;。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    一.&amp;nbsp;epoll的边沿触发(ET)的效率高于电平(LT)触发的效率
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;首先简单介绍一个背景：epoll实现中，把已经有事件发生的文件用一个双链表链接一起，这个双链表是在struct&amp;nbsp;eventpoll结构中的rdllist域。用户空间调用epoll_wait()，陷入内核后就会立即检查这个双链表，如果链表中非空，就通过文件的poll()函数询问文件有无事件发生。如果有事件发生且是用户关心的，就会向用户空间报告，否则就睡眠。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;epoll的实现代码中实际上只有两行代码与触发方式有关，如下图所示。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;265&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-17809.png&#34; width=&#34;554&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;上图所示的代码运行的上下文情况是：用户加入到epoll中的某个文件，只要支持poll()，(可以是socket，FIFO，裸设备，whatever)有关心的事件到达(或可读，或可写，或报错)，内核空间已经把发生的事件复制到了用户空间，但还没有从内核态返回用户空间。在返回用户空间之前代码检查用被epoll监视的这个文件是否是ET触发，如果不是(那就是LT),就把监视的文件重新放回就绪队列，下次epoll_wait()调用的时候会立即重新检查这个文件有否有事件到达。如果这文件的确有事件发生，则epoll_wait()报告给调用者。如果没有，而且其它被监视的文件也没有事件发生，则调用epoll_wait()的task就让出处理器，开始睡觉(TASK_INTERRUPTIBLE)。这段逻辑在static&amp;nbsp;int&amp;nbsp;ep_poll(struct&amp;nbsp;eventpoll&amp;nbsp;*ep,&amp;nbsp;struct&amp;nbsp;epoll_event&amp;nbsp;__user&amp;nbsp;*events,&amp;nbsp;int&amp;nbsp;maxevents,&amp;nbsp;long&amp;nbsp;timeout)中，第1494行。
  &lt;/p&gt;
  &lt;p&gt;
    如果监听的文件开启的是边沿触发(默认)，则不会执行上图中的list_add_tail()逻辑。这就是边沿触发只会向用户报告一次，直到下一个关心事件发生才向用户空间报告的原因。
  &lt;/p&gt;
  &lt;p&gt;
    那么为什么ET触发效率高于LT触发呢？看一个例子，假如客户端监视一个TCP的Socket，服务端这时发来1M数据，客户端的主机网卡驱动缓存足够大，一次性接收到了所有1M数据。下面看两段客户端的接收伪代码(没有写read调用返回时socket被关闭的情况；另socket描述符fd被设为非阻塞)。
  &lt;/p&gt;
  &lt;p&gt;
    &lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;164&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-26818.png&#34; width=&#34;487&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;上图的代码使用了LT触发，这段代码依赖epoll_wait()通知还有数据可供读取。所以共调用了1024次epoll_wait()，1024次read()，共2048次系统调用才读完1M数据。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; height=&#34;242&#34; src=&#34;file:///C:\Users\KAMUSZ~1\AppData\Local\Temp\ksohtml\wps_clip_image-31492.png&#34; width=&#34;496&#34; /&gt;
  &lt;/p&gt;
  &lt;p&gt;
    上图使用ET触发，epoll_wait()只报告一次，然后代码循环调用1024次read()读完数据，直到第1025次read()返回-1，出错码为EAGAIN(EAGAIN等于EWOULDBLOCK)，于是代码知道已经接收完数据。一共只使用了1026次系统调用就读完了数据。
  &lt;/p&gt;
  &lt;p&gt;
    总结：即使使用电平触发也不要依赖epoll_wait()通知调用者到达事件，需要循环调用IO函数直到被通知EAGAIN，这样就把epoll_wait()的调用次数降到最低，仅管有可能在下次epoll_wait()时会有可能浪费一次文件的poll()调用，但这个很小的开销可以忽略。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    二.&amp;nbsp;为什么epoll支持嵌套调用
  &lt;/p&gt;
  &lt;p&gt;
    读epoll的实现代码发现，一个epoll的文件描述符epfd可以嵌套的加入另一个epoll。这样有什么用呢？
  &lt;/p&gt;
  &lt;p&gt;
    epoll的实现中&amp;ldquo;平等的&amp;rdquo;对待每个被监视的文件，它们维护在一棵红黑树之中，假如有十万个文件被监视，那么查找某个文件时就要在这十万个文件中查找。即使红黑树的查找效率是log(n)，文件非常大时也是比较消耗时间的。
  &lt;/p&gt;
  &lt;p&gt;
    那么假如有这样一种情况，如果这十万个文件中只有1000个是活跃的，或者说这1000个文件优先级最高。那么则有一种优化方案是，创建两个epoll，第一个epoll（epfd0）监控100000&amp;nbsp;&amp;#8211;&amp;nbsp;1000&amp;nbsp;个文件，第二个epoll&amp;nbsp;(epfd1)&amp;nbsp;监控1000个高优先级文件以及epfd0。这样的好处是，大多数情况下epoll实现只在1001个元素的红黑树中查找，自然效率提高了。
  &lt;/p&gt;
  &lt;p&gt;
    总结：epoll的嵌套调用给开发者提供了一个在高并发环境下的优化方案。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    三.&amp;nbsp;epoll的效率一定比select/poll高吗。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;答案是不一定。
  &lt;/p&gt;
  &lt;p&gt;
    Select的缺点大致有：
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;内核中写死了最多只能监视1024个文件.
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;每次调用select都要把关心的文件描述符和关心的文件件从一个用户空间的长长的数组拷贝到内核空间.
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;select若使得caller进程进入睡眠后，某个文件有事件到达此进程被唤醒，那么所有被监视的文件全部会被调用poll()询问&amp;ldquo;你有没有事件到达&amp;rdquo;，这是一个线性的时间复杂度。
  &lt;/p&gt;
  &lt;p&gt;
    epoll针对select的三个缺点的改进：
  &lt;/p&gt;
  &lt;p&gt;
    1.&amp;nbsp;监视的文件数由取决于系统中有多少低端内存(x86_64架构中的所有内存都是低端内存)。3.9.6版本的内核实现中，对于每个登录用户，最多使用系统中低端内存的4%用来创建监视用的数据结构。见第1951行代码。max_user_watches&amp;nbsp;=&amp;nbsp;(((si.totalram&amp;nbsp;&amp;#8211;&amp;nbsp;si.totalhigh)&amp;nbsp;/&amp;nbsp;25)&amp;nbsp;&lt;&lt;&amp;nbsp;PAGE_SHIFT)&amp;nbsp;/&amp;nbsp;EP_ITEM_COST;
  &lt;/p&gt;
  &lt;p&gt;
    2.&amp;nbsp;用户只需要把关心的文件对应的数据结构在调用epoll_wait()前用epoll_ctl()一次性传入内存，以后调用epoll_wait()时不需要像select一样拷贝大量数据。
  &lt;/p&gt;
  &lt;p&gt;
    3.&amp;nbsp;当调用epoll_wait()的caller进程睡眠时，突然有事件到达，caller进程被唤醒，epoll_wait()返回用户空间，内核并不遍历没有监视的文件，而只报告在一个即短时间内发生的事件。下面更详细的描述这个场景，以监视tcp&amp;nbsp;socket举例，大致是：某进程调用epoll_wait()，此时没有任何它关心的事件发生，于是caller进程进入睡眠。处理器调度了其它进程。数据到达时，当前进程被硬件中断，网卡驱动收到数据包，数据包在中断处理函数中被拷入内核，中断处理函数设置中断下半部(Half&amp;nbsp;Bottom)。下半部被处理器调度，调用epoll实现代码注册的回调函数ep_poll_callback()。ep_poll_callback()函数唤醒之前的caller进程，caller进程重新获得CPU，从epoll实现的ep_poll()函数中恢复执行，在3.9.6内核中的第1564行：&amp;nbsp;if&amp;nbsp;(!schedule_hrtimeout_range(to,&amp;nbsp;slack,&amp;nbsp;HRTIMER_MODE_ABS))。然后，内核代码开始收集已经就绪的文件和发生的事件，发回用户空间。只有从第一次回调函数ep_poll_callback()被驱动的代码调用（caller进程还在睡眠时执行的ep_poll_callback()算第一次）到epoll实现代码走到第586行关闭中断关闭中断的代码&amp;nbsp;spin_lock_irqsave(&amp;ep-&gt;lock,&amp;nbsp;flags);之间发生的事件才会被收集。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;对于第3点，这是epoll的优点，但在某种情况下却会是epoll的缺点。网上很多比较poll,&amp;nbsp;select,&amp;nbsp;epoll性能的文章，没来得及仔细看，我个人认为结论是可靠的。结论引入了一个概念active-to-total&amp;nbsp;ratio，设所有被监控的文件数是n，活跃的文件数是m，active-to-total比则是m/n，如果这个比非常高，比如大于0.7，则poll或select的性能要高过epoll，反之则epoll胜出。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;对比前文对select的第3个缺点和epoll的改进点3的叙述可以解释这个原因。因为select在返回用户空间前又轮循了所有关心的文件，而这些文件又大部分是有事件发生的，所以select所做的工作并没有浪费，但epoll只收集了一小段时间中发生的事件，于是select较之epoll减少了用户空间和内核空间的频繁切换，从而让select的性能反超epoll。
  &lt;/p&gt;
  &lt;p&gt;
    那么如何改进呢？明白了以上的原因，那么就可以对epoll做出改进，理论上对于active-to-total比较高的应用环境下，可以在epoll的实现中加入与select做法相同逻辑，即退出前询问所有的监控文件，反正active-to-total比很高。或者更好的方案，用一个链表链接活跃的文件，在epoll返回用户空间前遍历这个链表，争取每一个epoll_wait()调用返回尽可能多的事件。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    附：epoll的主要数据结构简介.
  &lt;/p&gt;
  &lt;p&gt;
    epoll接口的主要数据结构有struct&amp;nbsp;eventpoll，struct&amp;nbsp;epitem，struct&amp;nbsp;eppoll_entry。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;在讲述这三个数据结构前先提一下struct&amp;nbsp;file。Unix设计初期希望它的设计遵从&amp;ldquo;一切皆文件&amp;rdquo;的理念。在Linux内核中，每个抽象的文件对应一个内核struct&amp;nbsp;file结构体。Struct&amp;nbsp;file结构体中有一个void&amp;nbsp;*private_data域。不同的文件类型会在private_data域中存放特定的信息。Struct&amp;nbsp;file中另一个域f_op是函数指针的列表，它记录了对应该文件的操作。所有epoll文件的f_op都指向static&amp;nbsp;const&amp;nbsp;struct&amp;nbsp;&lt;a href=&#34;http://lxr.oss.org.cn/ident?i=file_operations&#34;&gt;file_operations&lt;/a&gt;&amp;nbsp;&lt;a href=&#34;http://lxr.oss.org.cn/ident?i=eventpoll_fops&#34;&gt;eventpoll_fops&lt;/a&gt;，因此可以代码判断一个文件是不是epoll如下：
  &lt;/p&gt;
  &lt;p&gt;
    static&amp;nbsp;inline&amp;nbsp;int&amp;nbsp;is_file_epoll(struct&amp;nbsp;file&amp;nbsp;*f)
  &lt;/p&gt;
  &lt;p&gt;
    {
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f-&gt;f_op&amp;nbsp;==&amp;nbsp;&amp;eventpoll_fops;
  &lt;/p&gt;
  &lt;p&gt;
    }
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;每次成功调用epoll_create时就会创建一个struct&amp;nbsp;file的结构体，和一个struct&amp;nbsp;eventpoll。Struct&amp;nbsp;file中的private_data指向struct&amp;nbsp;eventpoll。eventpoll维护了这个epoll的重要信息。其中比较重要的几个字段有：一个循环列表struct&amp;nbsp;list_head&amp;nbsp;&amp;nbsp;rdllist链接了该epll中已经可以读写或者有出错的文件描述符。一个红黑树的根结点struct&amp;nbsp;rb_root&amp;nbsp;&amp;nbsp;rbr，eventpoll维护了一棵红黑树，树中的结点是struct&amp;nbsp;epitem。
  &lt;/p&gt;
  &lt;p&gt;
    每个被加入到epoll中被关注的文件描述符都对应一个struct&amp;nbsp;epitem结构体。所有加入到同一个epoll中对应的所有epitem都挂在红黑树上。该红黑树的根结构保存在struct&amp;nbsp;eventpoll中。epitem中记录了对应的文件的文件描述符和文件指针。
  &lt;/p&gt;
  &lt;p&gt;
    struct&amp;nbsp;eppoll_entry是用来挂接到设备文件中的结构体。设备驱动在得知自己可读或可写或有错误时通过这个结构体通知有事件发生。每个eppoll_entry都指向一个epitem，一个epitem可能对应多个eppoll_entry。eppoll_entry中的域wait_queue_t&amp;nbsp;&amp;nbsp;wait就是被用来挂接到设备文件中的等待队列。设备文件通过wait可以拿到eppoll_entry，再通过eppoll_entry拿到epitem，再拿到eventpoll。
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Linux如何设置IPv6地址</title>
      <link>https://ykyi.net/?p=824/</link>
      <pubDate>Sun, 01 Jul 2012 08:46:32 +0000</pubDate>
      <guid>https://ykyi.net/?p=824/</guid>
      <description>&lt;p&gt;IPv6最终全面取待IPv6是不可逆的潮流。本文则讲一下在Linux下如何配置IPv6地址。当然本文假设你使用静态IP（不必是公共IPv6地址或公共IPv4地址，可以是私有IPv4地址）。本文不适用使用DHCP获取地址的情况。&lt;/p&gt;
&lt;p&gt;首先，你要确保你使用的Linux的内核已经支持IPv6。当前比较新的Linux都已经内建IPv6了。&lt;/p&gt;
&lt;p&gt;用root用户登录，运行：&lt;/p&gt;
&lt;p&gt;# lsmod | grep ipv6&lt;/p&gt;
&lt;p&gt;看看系统有没有已经加载了IPv6模块。如果没有，尝试用以下命令加载： &lt;/p&gt;
&lt;p&gt;# /sbin/modprobe ipv6&lt;/p&gt;
&lt;p&gt;第二，你需要有你的静态IP地址。&lt;/p&gt;
&lt;p&gt;**IPv4地址如何转成IPv6地址呢？**如果你的IP是一个IPv4地址，那么可以换算得到IPv6的地址形式。比较简单的作法可以去到 &lt;a href=&#34;http://grox.net/utils/ipv6.php&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;a href=&#34;http://grox.net/utils/ipv6.php&#34;&gt;http://grox.net/utils/ipv6.php&lt;/a&gt;&lt;/a&gt;。在左边的下拉列表中选择: IPv4 to 6to4 Address，在右边的编辑框中填上你的IPv4地址。点击: Calculate 则得到了你的IPv4地址的IPv6转化格式。&lt;/p&gt;
&lt;h2 id=&#34;配置ipv6地址&#34;&gt;配置IPv6地址&lt;/h2&gt;
&lt;p&gt;一般的Linux发行版用 /etc/network/interfaces 文件配置网卡。如果没有这个文件，那么请注意 /etc/network 目录下其它文件或者目录。&lt;/p&gt;
&lt;p&gt;假如要配置的Linux的静态IPv4地址是 192.168.1.10，这个IPv4地址转换成对应的IPv6地址则是 2002:c0a8:10a:: 。再提醒一下，上文提到过如何把IPv4地址转成IPv6地址。&lt;/p&gt;
&lt;p&gt;网关的IPv4地址是 192.168.1.1，这个IPv4地址转成对应的IPv6的地址是:2002:c0a8:0101:: 。&lt;/p&gt;
&lt;p&gt;那么 /etc/network/interfaces 文件应该配置成如下：&lt;/p&gt;
&lt;p&gt;#IPV6 static configuration(我是注释)&lt;br&gt;
iface eth0 inet6 static&lt;br&gt;
pre-up modprobe ipv6&lt;br&gt;
address 2002:c0a8:10a::&lt;br&gt;
netmask 64&lt;br&gt;
gateway 2002:c0a8:0101::&lt;/p&gt;
&lt;p&gt;注意 &amp;ldquo;pre-up&amp;rdquo; 命令。这一行保证系统在启动的时候加载支持ipv6的模块。&lt;br&gt;
最后重新启发动网络，如下：&lt;/p&gt;
&lt;p&gt;# /etc/init.d/networking restart&lt;/p&gt;
&lt;p&gt;你现在可以使用你的IPv6地址了。&lt;/p&gt;
&lt;h2 id=&#34;测试ipv6地址&#34;&gt;测试IPv6地址：&lt;/h2&gt;
&lt;p&gt;检测路由：&lt;/p&gt;
&lt;p&gt;# ip -6 route show&lt;/p&gt;
&lt;p&gt;如果IPv6工作正常的话，应该会有如下的提示。&lt;/p&gt;
&lt;p&gt;2002:c0a8:0100/64 dev eth0 proto kernel scope link src 2002:c0a8:10a&lt;/p&gt;</description>
    </item>
    <item>
      <title>traceroute failed.Specify protocal traceroute used manually to fix it.</title>
      <link>https://ykyi.net/?p=751/</link>
      <pubDate>Wed, 20 Jun 2012 14:37:16 +0000</pubDate>
      <guid>https://ykyi.net/?p=751/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;Today, I ran the traceroute program on a machine running FreeBSD. It failed once and again.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;Traceroute complained:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;&lt;span style=&#34;color: rgb(51, 51, 51); line-height: 19px; text-align: left; &#34;&gt;traceroute: sendto: Permission denied.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&#34;text-align: left;&#34;&gt;
  &lt;span style=&#34;font-family:lucida sans unicode,lucida grande,sans-serif;&#34;&gt;&lt;span style=&#34;font-size: 16px; &#34;&gt;&lt;font color=&#34;#333333&#34;&gt;&lt;span style=&#34;line-height: 19px; &#34;&gt;So I tried to ping. Ping failed, too. I then checked out the configuration of the firewall, which actually denied the pass through of ICMP packet. So I set it to allow ICMP pacakges to pass through the firewall. Ping worked as I expected. But traceroute still failed.&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第13章 Daemon Processes and the inetd Superserver 笔记</title>
      <link>https://ykyi.net/?p=356/</link>
      <pubDate>Mon, 26 Dec 2011 16:59:47 +0000</pubDate>
      <guid>https://ykyi.net/?p=356/</guid>
      <description>&lt;p&gt;# The syslogd daemon runs in an infinite loop that calls select, waiting for any one of its three descriptors to be readable. it reads the log message and does what the configuration file says to do with that message. If the daemon receives the SIGHUP signal, it rereads its configuration file. So, what are the three descriptors that the select system call is waiting for ?  1. A unix domain socket is created and bound to the pathname /var/run/log (/dev/log on some systems). 2. A udp socket is created and bound to port 514(the syslog service). 3. The pathname /devklog is opened. Any error messages from within the kernel appears as input on this device. Newer implementation disable the creation of the UDP socket, unless specified by the administrator, as allowing anyone to send UDP datagrams to this port opens the system up to denial-of-service attacks, where some one could fill up the filesystem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第十二章 IPv4 and IPv6 Interoperability</title>
      <link>https://ykyi.net/?p=352/</link>
      <pubDate>Mon, 26 Dec 2011 13:28:35 +0000</pubDate>
      <guid>https://ykyi.net/?p=352/</guid>
      <description>&lt;p&gt;# Ethernet header contains a type fileld of 0x0800, which identifies the frame as an IPv4 frame.&lt;/p&gt;
&lt;p&gt;# 若支持dual-stack的server既有IPv4又有IPv6。则IP层让server透明地既可处理IPv4又可处理IPv6.该server需要绑定到wildcard且未设置IPV6_V6ONLY socket option.&lt;/p&gt;
&lt;p&gt;# UNP Page359 Figure 12.5 Summary of interoperability between IPv4 and IPv6 clients and servers.&lt;/p&gt;
&lt;p&gt;# 尽可能用IPv6,  since an IPv6 client can still communicate with IPv4 servers, and vice versa.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程 第11章 Name and Address Conversions 笔记</title>
      <link>https://ykyi.net/?p=344/</link>
      <pubDate>Mon, 26 Dec 2011 12:48:53 +0000</pubDate>
      <guid>https://ykyi.net/?p=344/</guid>
      <description>&lt;p&gt;# gethostbyname 和 gethostbyaddr 用来在 IPv4 地址和 hostname 之间转换. getservbyport 和 getservbyname 则是与服务相关。gethostbyname出错时不设errno而是设h_errno，并有hstrerror()函数。&lt;/p&gt;
&lt;p&gt;# FQDN的全称是: Fully Qualified domain name. 技术上说必须以点号(period)终止.&lt;/p&gt;
&lt;p&gt;# AAAA 被称为 &amp;ldquo;quad A&amp;rdquo; rcord, 给出了从hostname到Ipv6地址的映射。 PTR用来把IP地址到hostname.&lt;/p&gt;
&lt;p&gt;# Entries in the DNS are known as Resource Records(RRs).&lt;/p&gt;
&lt;p&gt;# 一个点分十进制(dotted-decimal)IPv4的地址前加 0::ffff:就是 IPv6的字符串形式。&lt;/p&gt;
&lt;p&gt;# 与getpeername对应的函数不是gethostname而是getsockname.&lt;/p&gt;
&lt;p&gt;# getaddrinfo函数的host参数指定为dotted-decimal IPv4或 IPv6 hex string,会使得只有IPv4或IPv6的addrinfo返回。&lt;/p&gt;
&lt;p&gt;# 不给UDP套接字设置SO_REUSEADDR选项。We do not set the SO_REUSEADDR socket option for the UDP socket because this socket option can allow multiple sockets to bind the same UDP port on hosts that support multicasting. Since there is nothing like TCP&amp;rsquo;s TIME_WAIT state for a UDP socket, there is no need to set this socket option when the server is started.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix 网络编程 第十章 SCTP Client/Server Example</title>
      <link>https://ykyi.net/?p=313/</link>
      <pubDate>Mon, 19 Dec 2011 11:25:57 +0000</pubDate>
      <guid>https://ykyi.net/?p=313/</guid>
      <description>&lt;p&gt;这一章的内容还是满少的。也就是给出一个SCTP的简单例子。所以也没有太多需要做笔记的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;什么是 head-of-line blocking.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Head-of-line blocking occurs when a TCP segment is lost and a subsequent TCP segment arrives out of order. That subsequent segment is held until the first TCP segment is retransmitted and arrives at the receiver.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;怎么更改SCTP连接的stream的数量。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SCTP连接的streams的数量是在association的握手之前协商好的。对于FreeBSD的KAME实现，SCTP的outbound streams默认为10。这个值可以用setsocket函数更改。与SCTP_INITMSG scoket option相关，设置struct sctp_initmsg结构体。&lt;/p&gt;
&lt;p&gt;也可以用sendmsg函数发送ancillary数据来到达同样的目标。但发送ancillary data只对one-to-many形式的sctp socket有效。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;怎么结束一个SCTP连接。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以设置sctp_sndrcvinfo结构的sinfo_flags值的MSG_EOF flag来关闭一个sctp连接gracefully. This flag forces an association to shut down after the message being sent is acknowledged.&lt;/p&gt;
&lt;p&gt;还可以给sinfo_flags设置 MSG_ABORT。这样就会立即发送一个ABORT给peer端。任何还没来得及发送出的数据会被丢弃。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第九章笔记</title>
      <link>https://ykyi.net/?p=307/</link>
      <pubDate>Sat, 17 Dec 2011 08:58:14 +0000</pubDate>
      <guid>https://ykyi.net/?p=307/</guid>
      <description>&lt;p&gt;# TCP 协议在1981年标准化，而SCTP协议则是在2000年由IETF组织标准化。IETF： Internet Engineering Task Force 互联网工程任务组成立于1985年。&lt;/p&gt;
&lt;p&gt;# SCTP支持两种类型的socket. one to one(为了方便现有的tcp程序迁移到sctp) 和 one to many.&lt;/p&gt;
&lt;p&gt;# sctp的sctp_bindx可以绑定多个地址，并且可以动态增删。但动态增删不影响已经存在的associations.不过各个unix分支不一定支持这个特性。&lt;/p&gt;
&lt;p&gt;# sctp_getpaddrs和sctp_getladdrs分别是getpeername和gethostname的sctp版。They are designed with the concept of a multihoming aware transport protocol.&lt;/p&gt;
&lt;p&gt;# sctp传输的报文是有边界的。sctp在传输层支持传输超大的message.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第七章笔记</title>
      <link>https://ykyi.net/?p=296/</link>
      <pubDate>Thu, 15 Dec 2011 06:33:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=296/</guid>
      <description>&lt;div&gt;
  1.&amp;nbsp;有一个&amp;nbsp;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Generic&amp;nbsp;Socket&amp;nbsp;Option&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;：&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_BROADCAST&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;用来开启是否充许广播。&lt;/span&gt;2.&amp;nbsp;仅有&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;支持&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_DEBUG&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;把详细的发送包的接收包信息存在一个环路&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里。可以用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;trpt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;查看它。&lt;/span&gt;3.&amp;nbsp;SO_ERROR&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字选项只能被取得，不能被设置。如果进程阻塞在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;select&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调用里，不论是读还是写，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;select&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;都会返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;conditions&amp;nbsp;set&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果进程使用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;signal-driven&amp;nbsp;I/O&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SIGIO&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;信号会被发到这个进程或者它所在的进程组。进程用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;getsockopt&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;得到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会被重置为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，此时调用&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;或者&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;write&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会立即返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;-1&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;errno&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;被置为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;so_error&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的值。&lt;/span&gt;&lt;/p&gt; 
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    &amp;nbsp;
  &lt;/p&gt;
  &lt;p&gt;
    4.&amp;nbsp;SO_KEEPALIVE&lt;span style=&#34;font-family: 宋体;&#34;&gt;在一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;连接没有任何收发达两个小时时会发一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;prob&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给对方。两个钟喔。好长的时间啊！！！&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Richard&amp;nbsp;Stevens&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;认为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_KEEPALIVE&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;应该改叫&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;make-dead&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。大多&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Unix&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;把这个两小时时长存为一个系统级的变量。这意味着如果你用某种方法改变了这个时长，会影响这个操作系统的所有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket.Richard&amp;nbsp;Stevens&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;认为想把这个时长改短的想法是错误理解了这个选项的意义。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    5.&amp;nbsp;SO_LINGER&lt;span style=&#34;font-family: 宋体;&#34;&gt;仅仅适用于面向连接的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，比如&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;和&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，因此不适用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;UDP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    Struct&amp;nbsp;linger{
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;l_onofff;
  &lt;/p&gt;
  &lt;p&gt;
    int&amp;nbsp;l_linger;
  &lt;/p&gt;
  &lt;p&gt;
    };
  &lt;/p&gt;
  &lt;p&gt;
    L_onoff&lt;span style=&#34;font-family: 宋体;&#34;&gt;为零是，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;behavior&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就是默认情况：&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;立即返回，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;继续发送缓冲区内未发送的数据。当&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_onoff&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为零，而&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_linger&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;协议则会立即终止连接，发送&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;RST&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端，这样做避免了&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TCP&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;TIME_WAIT&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;状态，这样的坏处是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;:&amp;nbsp;leaves&amp;nbsp;open&amp;nbsp;the&amp;nbsp;possibility&amp;nbsp;of&amp;nbsp;another&amp;nbsp;incarnation&amp;nbsp;of&amp;nbsp;this&amp;nbsp;connection&amp;nbsp;being&amp;nbsp;created&amp;nbsp;within&amp;nbsp;2MSL&amp;nbsp;seconds&amp;nbsp;and&amp;nbsp;having&amp;nbsp;old&amp;nbsp;duplicate&amp;nbsp;segments&amp;nbsp;from&amp;nbsp;the&amp;nbsp;just-terminated&amp;nbsp;connection&amp;nbsp;being&amp;nbsp;incorrectly&amp;nbsp;delivered&amp;nbsp;to&amp;nbsp;the&amp;nbsp;new&amp;nbsp;incarnation.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;对于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP,&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;也会发送一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ABORT&amp;nbsp;chunk&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;第三种情况：如果&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_onoff&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;为真，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;l_linger&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不为&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;不会立即返回，会最多等待指定的时长，在这段时间里&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;kernel&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;发送缓冲区内的数据给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果在这段时间内发送完则&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;0.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;如果没有发送完毕，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就会返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;EWOULDBLOCK&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里的数据会被丢弃。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    6.&amp;nbsp;MSL:&amp;nbsp;maximum&amp;nbsp;segment&amp;nbsp;lifetime.
  &lt;/p&gt;
  &lt;p&gt;
    7.&amp;nbsp;因此&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;默认情况下立即返回，即使用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SO_LINGER&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;设置等待时间也在理论上存在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;先于发送缓冲区的数据被&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;acknowleded&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的情况。因此一个更好的解决方案是用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shutdown&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;系统调用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;with&amp;nbsp;a&amp;nbsp;second&amp;nbsp;argument&amp;nbsp;of&amp;nbsp;SHUT_WR&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。在调用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shutdown&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;后，用&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;调用直到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;read&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;返回&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，即收到&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;FIN&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    8.&amp;nbsp;UDP&lt;span style=&#34;font-family: 宋体;&#34;&gt;没有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;congestion&amp;nbsp;control&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，如果发得太快，不仅仅&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;peer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;端来不及收。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;A&amp;nbsp;fast&amp;nbsp;sender&amp;nbsp;can&amp;nbsp;overwhelm&amp;nbsp;its&amp;nbsp;own&amp;nbsp;network&amp;nbsp;interface,&amp;nbsp;causing&amp;nbsp;datagrams&amp;nbsp;to&amp;nbsp;be&amp;nbsp;discarded&amp;nbsp;by&amp;nbsp;the&amp;nbsp;sender&amp;nbsp;itself.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    9.&amp;nbsp;因为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;在三次握手阶段的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SYN&amp;nbsp;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;里交换窗口大小&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(windows&amp;nbsp;scale)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。所以&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的接收缓冲大小必须在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;shank&amp;nbsp;hands&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;之前就设置好。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Connected&amp;nbsp;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;从&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;listening&amp;nbsp;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;继承这个选项。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    10.&amp;nbsp;TCP&lt;span style=&#34;font-family: 宋体;&#34;&gt;的套接字缓冲区大小至少需要是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;倍&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的大小。&lt;/span&gt;这里指的套接字缓冲，如果是针对单向的传输，比如单向传一个文件，指的是发送方的发送缓冲和接收方的接收缓冲。如果是双向的传输，则指的是双方的接收和发送缓冲。为什么&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字的缓冲区需要至少&amp;nbsp;&amp;nbsp;&amp;nbsp;是&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;倍&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的大小呢？&lt;/span&gt;这是因为&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;tcp&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的快恢复&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;(fast&amp;nbsp;recovery)&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法。快恢复算法定义：如果接收端连续收到三个同样的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ACK&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，就认为有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;packet&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;丢失了。而接收端在&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;丢失后，每收到新的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segment&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就不停地重发一个重复的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ack&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;给&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;sender&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;。如果窗口大小小于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;segments,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;就不会有三个重复的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;ACK,&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;所以快恢复算法就没办法工作了。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    11.&amp;nbsp;What&amp;nbsp;is&amp;nbsp;bandwidth-delay&amp;nbsp;product.
  &lt;/p&gt;
  &lt;p&gt;
    A:&amp;nbsp;The&amp;nbsp;capacity&amp;nbsp;of&amp;nbsp;the&amp;nbsp;pipe&amp;nbsp;is&amp;nbsp;called&amp;nbsp;the&amp;nbsp;bandwidth-delay&amp;nbsp;product&amp;nbsp;and&amp;nbsp;we&amp;nbsp;calculate&amp;nbsp;this&amp;nbsp;by&amp;nbsp;multiplying&amp;nbsp;the&amp;nbsp;bandwidth(in&amp;nbsp;bits/sec)&amp;nbsp;times&amp;nbsp;the&amp;nbsp;RTT(in&amp;nbsp;seconds),&amp;nbsp;converting&amp;nbsp;the&amp;nbsp;result&amp;nbsp;from&amp;nbsp;bits&amp;nbsp;to&amp;nbsp;bytes.&amp;nbsp;&lt;span style=&#34;font-family: 宋体;&#34;&gt;即网速乘上&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;RTT.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    12.&amp;nbsp;UDP&lt;span style=&#34;font-family: 宋体;&#34;&gt;没有&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，但有一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;send&amp;nbsp;buffer&amp;nbsp;size.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;只要&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;socket&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;buffer&amp;nbsp;size&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;大于&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;LO_WATER&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;，就永远是可写的。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    13.&amp;nbsp;SO_REUSEADDR&lt;span style=&#34;font-family: 宋体;&#34;&gt;有四种用途。好难写。见&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;Unix&amp;nbsp;Network&amp;nbsp;Programming&amp;nbsp;Section&amp;nbsp;7.5&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;影印版第&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;211&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;页啦。&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    14.&amp;nbsp;It&#39;s&amp;nbsp;Ok&amp;nbsp;for&amp;nbsp;the&amp;nbsp;MSS&amp;nbsp;to&amp;nbsp;be&amp;nbsp;different&amp;nbsp;in&amp;nbsp;each&amp;nbsp;direction.
  &lt;/p&gt;
  &lt;p&gt;
    15.&amp;nbsp;Nagle&lt;span style=&#34;font-family: 宋体;&#34;&gt;算法是为了减少&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;small&amp;nbsp;package&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;的数量.&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;The&amp;nbsp;algorithm&amp;nbsp;states&amp;nbsp;that&amp;nbsp;if&amp;nbsp;a&amp;nbsp;given&amp;nbsp;connection&amp;nbsp;has&amp;nbsp;outstanding&amp;nbsp;data,&amp;nbsp;then&amp;nbsp;no&amp;nbsp;small&amp;nbsp;packets&amp;nbsp;will&amp;nbsp;be&amp;nbsp;sent&amp;nbsp;on&amp;nbsp;the&amp;nbsp;connection&amp;nbsp;in&amp;nbsp;response&amp;nbsp;to&amp;nbsp;a&amp;nbsp;user&amp;nbsp;write&amp;nbsp;operation&amp;nbsp;until&amp;nbsp;the&amp;nbsp;existing&amp;nbsp;data&amp;nbsp;is&amp;nbsp;acknowledged.&amp;nbsp;Small&amp;nbsp;package&amp;nbsp;&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;指的是任何比&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;MSS&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;小的&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;package.&lt;/span&gt;
  &lt;/p&gt;
  &lt;p&gt;
    16.&amp;nbsp;Delayed&amp;nbsp;ACK&amp;nbsp;algorithm:&amp;nbsp;This&amp;nbsp;algorithm&amp;nbsp;causes&amp;nbsp;TCP&amp;nbsp;to&amp;nbsp;not&amp;nbsp;send&amp;nbsp;an&amp;nbsp;ACK&amp;nbsp;immediately&amp;nbsp;when&amp;nbsp;it&amp;nbsp;receives&amp;nbsp;data;&amp;nbsp;instead,&amp;nbsp;TCP&amp;nbsp;will&amp;nbsp;wait&amp;nbsp;some&amp;nbsp;small&amp;nbsp;amount&amp;nbsp;of&amp;nbsp;time&amp;nbsp;(typically&amp;nbsp;50-200ms)and&amp;nbsp;only&amp;nbsp;then&amp;nbsp;send&amp;nbsp;the&amp;nbsp;ACK.
  &lt;/p&gt;
  &lt;p&gt;
    17.&amp;nbsp;SCTP&lt;span style=&#34;font-family: 宋体;&#34;&gt;有一个&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP_AUTOCLOSE&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;套接字选项。&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;This&amp;nbsp;option&amp;nbsp;allows&amp;nbsp;us&amp;nbsp;to&amp;nbsp;fetch&amp;nbsp;or&amp;nbsp;set&amp;nbsp;the&amp;nbsp;autoclose&amp;nbsp;time&amp;nbsp;for&amp;nbsp;an&amp;nbsp;SCTP&amp;nbsp;endpoint.&amp;nbsp;The&amp;nbsp;autoclose&amp;nbsp;time&amp;nbsp;is&amp;nbsp;the&amp;nbsp;number&amp;nbsp;of&amp;nbsp;seconds&amp;nbsp;an&amp;nbsp;SCTP&amp;nbsp;association&amp;nbsp;will&amp;nbsp;remain&amp;nbsp;open&amp;nbsp;when&amp;nbsp;idle.&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;即&lt;/span&gt;&lt;span style=&#34;font-family: Times New Roman;&#34;&gt;SCTP&amp;nbsp;association&lt;/span&gt;&lt;span style=&#34;font-family: 宋体;&#34;&gt;能够保持空闲状态的最长时间。超时就会被关闭。&lt;/span&gt;
  &lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    <item>
      <title>Unix网络编程.第五，六章笔记.</title>
      <link>https://ykyi.net/?p=284/</link>
      <pubDate>Sat, 10 Dec 2011 13:56:00 +0000</pubDate>
      <guid>https://ykyi.net/?p=284/</guid>
      <description>&lt;p&gt;# Unix世界里经常看到的 pst  是 pseudo terminal 的意思啊。&lt;/p&gt;
&lt;p&gt;# ps -t pts/6 -o pid,ppid,tty,stat,args,wchan&lt;/p&gt;
&lt;p&gt;ps 命令的进程状态。 S表示进程在睡眠，I表示进程在等待输入，O表示进程在等待输出。当进程在S状态时，wlan指示了更详细的状态信息。&lt;/p&gt;
&lt;p&gt;# SIGSTOP 和 SIGKILL 两个posix信号不可以被caught.&lt;/p&gt;
&lt;p&gt;# 缺省情况下，Unix的信号是不排在队列中的。这意味着多个相同signal到达的时候如果没有来得及处理，就只会记下一个signal.如果需要稳定的信号支持，就要使用RealTime Posix接口。&lt;/p&gt;
&lt;p&gt;# init 进程的PID是 1.&lt;/p&gt;
&lt;p&gt;# 可以用sigprocmask函数block和unblock信号。This let us protect a critical region of code by preventing certain signals from being caught while that region of code is executing.&lt;/p&gt;
&lt;p&gt;# 对于 Unix System V 和 Unix98, the child of a process does not become a zombie if the process sets the disposition of SIGCHLD to SIG_IGN. unfortunately, tis works only under System V &amp;amp; Unix98. Posix明确指票这个行为是未定义的。The portable way to handle zombies is to catch SIGCHILD &amp;amp; call wait or waitpid.&lt;/p&gt;</description>
    </item>
    <item>
      <title>fsockopen真好用,PHP的高级别网络函数！</title>
      <link>https://ykyi.net/?p=67/</link>
      <pubDate>Mon, 01 Nov 2010 16:42:36 +0000</pubDate>
      <guid>https://ykyi.net/?p=67/</guid>
      <description>&lt;p&gt;今天用&lt;a href=&#34;http://ykyi.net/?p=40&#34;&gt;Burp工具&lt;/a&gt;分析了一个网站的大致功能后打算写程序把该网站我感兴趣的内容全抓下来。&lt;br&gt;
一开始用java写了一小段，但哥对Java不熟悉哇，而且哥觉得Java的那么多流的类，如果仅仅操作文本文件，就显得封装的太厚了。又想，用C/C++写。虽然用C/C++写的最多代码，但事实上C/C++的字符串操作一想起来就嫌烦，而且正则式也烂得可以，数组不支持用字符串索引也真够麻烦，虽然可用C++的std::map容器。最后决定用PHP写…PHP真是太好用了~~~犹赞超强大的正则式，同perl的正则式有得一拼啊。如果换用标准C字符串函数和GNU的一个超难用的C正则式库，那要写死人啊~~~&lt;/p&gt;
&lt;p&gt;最开始的思维定势就是要先开一个socket(N多参数要填入), 省略bind(操作系统自已选一个本地端口绑定)，第二步 connect 到主机，第三步往 socket 里写东西… 虽然只几个简单函数，但要填的几个参数也真够难记的。嘿，偶像发现事实上PHP提供了high-level的socket函数 fsockopen()。哇，太方便了。&lt;/p&gt;
&lt;p&gt;fsockopen()&lt;br&gt;
returns a file pointer which may be used together with the other file functions (such as fgets(), fgetss(), fwrite(), fclose(), and feof())&lt;br&gt;
fsocketopen返回一个文件指针，然后就可以用常用的文件函数操作它啦！！！和操作文本一件一样~~~ 比 Java 的 java.io.socket 类还要方便~~虽然java也抽象的不错，但我就是嫌流对象封装太厚了。人生苦短，何必自找麻烦呢。&lt;br&gt;
用完以后用 fclose 把它fsockopen返回的文件指针关掉！&lt;/p&gt;
&lt;p&gt;看个例程:&lt;/p&gt;
&lt;?php&lt;br /&gt; $fp = fsockopen(&amp;#8220;udp://127.0.0.1&amp;#8221;, 13, $errno, $errstr);

  
if (!$fp) {  
echo &amp;#8220;ERROR: $errno &amp;#8211; $errstr  
\n&amp;#8221;;  
} else {  
fwrite($fp, &amp;#8220;\n&amp;#8221;);  
echo fread($fp, 26);  
fclose($fp);  
}  
?&gt;  
&lt;p&gt;上面的例程从本机的UDP时间服务器里读取当时的时间和日期。如果你本机开了标准的时间服务的话~~~&lt;/p&gt;</description>
    </item>
    <item>
      <title>tcpdump基础教程</title>
      <link>https://ykyi.net/?p=45/</link>
      <pubDate>Sun, 31 Oct 2010 05:34:49 +0000</pubDate>
      <guid>https://ykyi.net/?p=45/</guid>
      <description>&lt;p&gt;英文原文出自： &lt;a href=&#34;http://danielmiessler.com/study/tcpdump/&#34;&gt;A tcpdump Tutorial and Primer&lt;/a&gt;&lt;br&gt;
翻译: ykyi.net&lt;/p&gt;
&lt;p&gt;Tcpdump是信息安全专业人士最重要的一个网络分析工具。对这个工具有一个深入的理解对于每一个喜欢透彻理解tcp/ip协议栈的人来话都是必须的。但很多人选择一个更高级别的工级，比如Ethereal Wireshark，但是我认为这是一个错误！&lt;/p&gt;
&lt;p&gt;不应该机械的反复记忆概念而应该做到真正的理解，因为对tcp/ip协议簇保持清醒的认知非常的重要。如果对该协议簇能够完全精通，那你调试网络的能力则能比同行们高出几个档次。但是，要学精神tcp/ip协议簇，只有不够的实践剖析它们才能做到。&lt;/p&gt;
&lt;p&gt;当你使用某种工具来显示网络中的原始流量信息时，人类，而不是机器，就要承担起分析这些流量的重任了。用这种方法就可以不断地加深对tcp/ip的理解。并且，用这种学习方法的时候，我在任何可能的情况下都强烈主张使用tcpdump而不是其它工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;选项&lt;/strong&gt;&lt;br&gt;
下面将列出一些用例子的选项，这样可以在你使用这个工具时对你有很大的帮助。这些选项很容易淡忘或与其它类型的滤镜(Filter,笔者认为这里的滤镜实际上指的是其它网络工具)混淆。比如, ethereal。所以，希望这篇文章可以作为一个参考文档，我就是这样使用它的。&lt;/p&gt;
&lt;p&gt;首先，我要先介绍几个我认为很方便的tcpdump的选项。第一个是 -n, 这样的话域名就不会被解析了，而是用数字IP的形式显示地址(译者注: 同netstat的-n是一样的喔)。第二个是 -X, 这样就会同时把包的内容以ASCII码和十六制的形式显示。最后一个是 -S, 它个选项会显示绝对序号而不是相对序号。因为当包被隐藏起来的话，你也不会看到奇怪的序号。请谨记，tcpdump较之其它工具的优势之一就是可以与包(packets)手工交互。&lt;/p&gt;
&lt;p&gt;值得注意的是，tcpdump默认只会从packet中取出前96个字节。如果你想要多一些的话，那就需要需要把 -s xxxx 加上。这里的xxxx是你确切想要抓取的总字节数。如果我使用这个选项的话，我通常会把这个数字设定为1514而得到所有的数据。下面是一个简短的列表列出我经常使用的选项。&lt;/p&gt;
&lt;p&gt;-i any: 监听所有的介面。这样你就知道是不是有流量产生。&lt;br&gt;
-n: 不要解决主机名，以IP数字形式显示主机。&lt;br&gt;
-nn: 不要解析主机名或端口名字。&lt;/p&gt;
&lt;p&gt;-A: 以ASCII字符显示包的数据。&lt;br&gt;
-X: 同时以十六进制和ASCII字符显示包的数据。&lt;br&gt;
-XX: 同-X,但也会显示 Ethernet头部。&lt;br&gt;
-v, -vv, -vvv: 详细，更详细，再详细些！ 冗余输出得到的包信息。&lt;br&gt;
-c: 抓取 x 个包后就停下。&lt;br&gt;
-S: 打印绝对序号。&lt;br&gt;
-e: 同时得到Ethernet头部。&lt;br&gt;
-q: 显示少一点协议信息。&lt;br&gt;
-E: 用提供的密钥解密 IPSEC 流量。&lt;br&gt;
-s: 设置显示前多少个字节的包内容（snaplength）。&lt;/p&gt;
&lt;p&gt;tcpdump 4.0的snaplength的长度从68字节改成了96字节，这样你就可以看到多些内容了。但仍然看不到所有的内容，指定 -s 1514 得到包的所有内容。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://ykyi.net&#34;&gt;http://ykyi.net&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;一些基本的应用&lt;/strong&gt;&lt;br&gt;
根据我要查看的不同流量，我使用不同的选项组合，如下:&lt;/p&gt;
&lt;p&gt;1.Basic communication // see the basics without many options&lt;br&gt;
tcpdump -nS&lt;/p&gt;</description>
    </item>
    <item>
      <title>Burp套件教程(Burp Suite)</title>
      <link>https://ykyi.net/?p=40/</link>
      <pubDate>Thu, 28 Oct 2010 17:01:40 +0000</pubDate>
      <guid>https://ykyi.net/?p=40/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;http://portswigger.net/burp/&#34;&gt;原文来自http://portswigger.net/burp/&lt;/a&gt;&lt;br&gt;
ykyi.net 翻译&lt;/p&gt;
&lt;p&gt;使用Burp套件(Burp Suite)&lt;br&gt;
当启动Burp Suite以后，Burp的代理服务器就在本地的loopback介面上的8080端口上开始运行啦！通过设定浏览器使用这个Burp代理服务器，所有的WEB流量就可以被截获，窥视，修改。默认设置下，对非媒体资源(non-media)的请求将被截获而且显示出来(默认的设置可以在Burp Proxy的OPTION选项里修改）。所有的穿过Burp代理服务器的WEB流量将被自动分析并添加到站点地图里，这样就可以知道访问过的网站的内容和功能了。对于Burp的收费Professional版，默认情况下，所有的请求还会自动被Burp Scanner分析从而确定易受攻击的部分。&lt;/p&gt;
&lt;p&gt;在你就要刻苦大干一场之前，你需要完美地定义出你的工作的Target Scope(Burp的术语名词，不译出)。最简单的办法就是先浏览目标网站，然后定位相关主机和目录，再使用context菜单项把URL们添加到Target Scope里。中央范围配置(Central Scope Configuration)可以用来配置各个Burp工具。&lt;/p&gt;
&lt;p&gt;当你浏览目录WEB网站或程序的时候，你就能对截获的请求和响应进行手工编辑，或者你也可以完全关闭拦截功能。在拦截功能被关闭的情况下，每一条请求和响应仍然被记在历史记录里，所有的WEB内容也会被添加到站点地图里。&lt;/p&gt;
&lt;p&gt;除了可以用代理修改拦截下面的讯息，你也可以把迅息发送到其它Burp工具。这样就可以完成各种各样的不同的功能，比如：&lt;/p&gt;
&lt;p&gt;》你可以通过把请求发给Repeater来手动调节对WEB程序的测试，也可以不断地重发每个请求。&lt;br&gt;
》对于Professional版，可以把请求发给Scanner，就可以完成主动和被动漏洞扫描。&lt;br&gt;
》你可以把请求发给Intruder，就可以发起一个用户自定义的自动测试来确定一些常见的漏洞。&lt;br&gt;
》如果你发现响应中有会话令牌或者其它本应该是不可预测的ID号，你就可以把这个响应发给Sequencer来测试这个令牌的随机性。&lt;br&gt;
》可以把请求或响应中被模糊化处理的数据发给Decoder来尝试自动解析出明文。&lt;br&gt;
》对于Professional版，你可以使用各种Engagement工具来提高你的工作效率。&lt;br&gt;
对于代理的历史记录，站点地图中的主机·目录·文件 以及Burp工具的任何显示请求和响应的地方 你都可以执行以上任何操作。&lt;/p&gt;
&lt;p&gt;中央日志功能(central logging function)记录下来每个Burp工具的所有的响应和请求。每个Burp工具都可以在单独的窗口中运行也可以在TAB WINDOW下运行。每个工具和整个套件的配置可以被保存下来重复使用。对于Professional版，你还可以保存每个工具的状态，这样你就可以随心所欲的重新载入之前保存的状态。&lt;/p&gt;
&lt;p&gt;copyright ykyi.net&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
