﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-一江春水向东流-文章分类-互联网</title><link>http://www.blogjava.net/huyi2006/category/36109.html</link><description>                            做一个有思想的人,期待与每一位热爱思考的人交流,您的关注是对我最大的支持。</description><language>zh-cn</language><lastBuildDate>Tue, 12 Jun 2012 09:23:44 GMT</lastBuildDate><pubDate>Tue, 12 Jun 2012 09:23:44 GMT</pubDate><ttl>60</ttl><item><title>TCP长连接VS短连接 </title><link>http://www.blogjava.net/huyi2006/articles/380611.html</link><dc:creator>allic</dc:creator><author>allic</author><pubDate>Tue, 12 Jun 2012 07:38:00 GMT</pubDate><guid>http://www.blogjava.net/huyi2006/articles/380611.html</guid><wfw:comment>http://www.blogjava.net/huyi2006/comments/380611.html</wfw:comment><comments>http://www.blogjava.net/huyi2006/articles/380611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huyi2006/comments/commentRss/380611.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huyi2006/services/trackbacks/380611.html</trackback:ping><description><![CDATA[1. TCP连接

当网络通信时采用TCP协议时，在真正的读写操作之前，server与client之间必须建立一个连接，当读写操作完成后，双方不再需要这个连接时它们可以释放这个连接，连接的建立是需要三次握手的，而释放则需要4次握手，所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图：



经典的四次握手关闭图：



2. TCP短连接

我们模拟一下TCP短连接的情况，client向server发起连接请求，server接到请求，然后双方建立连接。client向server发送消息，server回应client，然后一次读写就完成了，这时候双方任何一个都可以发起close操作，不过一般都是client先发起close操作。为什么呢，一般的server不会回复完client后立即关闭连接的，当然不排除有特殊的情况。从上面的描述看，短连接一般只会在client/server间传递一次读写操作

短连接的优点是：管理起来比较简单，存在的连接都是有用的连接，不需要额外的控制手段

3.TCP长连接

接下来我们再模拟一下长连接的情况，client向server发起连接，server接受client连接，双方建立连接。Client与server完成一次读写之后，它们之间的连接并不会主动关闭，后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能，保活功能主要为服务器应用提供，服务器应用希望知道客户主机是否崩溃，从而可以代表客户使用资源。如果客户已经消失，使得服务器上保留一个半开放的连接，而服务器又在等待来自客户端的数据，则服务器将应远等待客户端的数据，保活功能就是试图在服务器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作，则服务器就向客户发一个探测报文段，客户主机必须处于以下4个状态之一：

客户主机依然正常运行，并从服务器可达。客户的TCP响应正常，而服务器也知道对方是正常的，服务器在两小时后将保活定时器复位。 
客户主机已经崩溃，并且关闭或者正在重新启动。在任何一种情况下，客户的TCP都没有响应。服务端将不能收到对探测的响应，并在75秒后超时。服务器总共发送10个这样的探测 ，每个间隔75秒。如果服务器没有收到一个响应，它就认为客户主机已经关闭并终止连接。 
客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应，这个响应是一个复位，使得服务器终止这个连接。 
客户机正常运行，但是服务器不可达，这种情况与2类似，TCP能发现的就是没有收到探查的响应。 
从上面可以看出，TCP保活功能主要为探测长连接的存活状况，不过这里存在一个问题，存活功能的探测周期太长，还有就是它只是探测TCP连接的存活，属于比较斯文的做法，遇到恶意的连接时，保活功能就不够使了。

在长连接的应用场景下，client端一般不会主动关闭它们之间的连接，Client与server之间的连接如果一直不关闭的话，会存在一个问题，随着客户端连接越来越多，server早晚有扛不住的时候，这时候server端需要采取一些策略，如关闭一些长时间没有读写事件发生的连接，这样可以避免一些恶意连接导致server端服务受损；如果条件再允许就可以以客户端机器为颗粒度，限制每个客户端的最大长连接数，这样可以完全避免某个蛋疼的客户端连累后端服务。

长连接和短连接的产生在于client和server采取的关闭策略，具体的应用场景采用具体的策略，没有十全十美的选择，只有合适的选择。

<img src ="http://www.blogjava.net/huyi2006/aggbug/380611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huyi2006/" target="_blank">allic</a> 2012-06-12 15:38 <a href="http://www.blogjava.net/huyi2006/articles/380611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>判断终端是来自手机</title><link>http://www.blogjava.net/huyi2006/articles/294242.html</link><dc:creator>allic</dc:creator><author>allic</author><pubDate>Tue, 08 Sep 2009 00:13:00 GMT</pubDate><guid>http://www.blogjava.net/huyi2006/articles/294242.html</guid><wfw:comment>http://www.blogjava.net/huyi2006/comments/294242.html</wfw:comment><comments>http://www.blogjava.net/huyi2006/articles/294242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huyi2006/comments/commentRss/294242.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huyi2006/services/trackbacks/294242.html</trackback:ping><description><![CDATA[function is_wap()
{
    $ua = strtolower($_SERVER['HTTP_USER_AGENT']); 
    $uachar = "/(nokia|sony|ericsson|mot|samsung|sgh|lg|sie|philips|panasonic|alcatel|lenovo|cldc|midp|wap|mobile)/i"; 
    if(($ua == '' || preg_match($uachar, $ua))&& !strpos(strtolower($_SERVER['REQUEST_URI']),'wap'))
    {//如果在访问的URL中已经找到 wap字样，表明已经在访问WAP页面，无需跳转，下一版本增加 feed访问时也不跳转 
        return true; 
    }else{ 
        return false; 
    } 
} 
<img src ="http://www.blogjava.net/huyi2006/aggbug/294242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huyi2006/" target="_blank">allic</a> 2009-09-08 08:13 <a href="http://www.blogjava.net/huyi2006/articles/294242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BT种子文件格式</title><link>http://www.blogjava.net/huyi2006/articles/241632.html</link><dc:creator>allic</dc:creator><author>allic</author><pubDate>Thu, 20 Nov 2008 06:08:00 GMT</pubDate><guid>http://www.blogjava.net/huyi2006/articles/241632.html</guid><wfw:comment>http://www.blogjava.net/huyi2006/comments/241632.html</wfw:comment><comments>http://www.blogjava.net/huyi2006/articles/241632.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/huyi2006/comments/commentRss/241632.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/huyi2006/services/trackbacks/241632.html</trackback:ping><description><![CDATA[
		<p align="left">BT种子文件使用了一种叫bencoding的编码方法来保存数据。<br />bencoding现有四种类型的数据：srings(字符串)，integers(整数)，lists(列表)，dictionaries(字典)<br />编码规则如下：<br />strings(字符串)编码为：&lt;字符串长度&gt;：&lt;字符串&gt;<br />例如： 4:test 表示为字符串"test"<br /> 4:例子 表示为字符串“例子”<br />字符串长度单位为字节<br />没开始或结束标记</p>
		<p>integers(整数)编码为：i&lt;整数&gt;e<br />开始标记i，结束标记为e<br />例如： i1234e 表示为整数1234<br /> i-1234e 表示为整数-1234<br />整数没有大小限制<br /> i0e 表示为整数0<br /> i-0e 为非法<br />以0开头的为非法如： i01234e 为非法</p>
		<p>lists(列表)编码为：l&lt;bencoding编码类型&gt;e<br />开始标记为l,结束标记为e<br />列表里可以包含任何bencoding编码类型，包括整数，字符串，列表，字典。<br />例如： l4:test5abcdee 表示为二个字符串["test","abcde"]</p>
		<p>dictionaries(字典)编码为d&lt;bencoding字符串&gt;&lt;bencoding编码类型&gt;e<br />开始标记为d,结束标记为e<br />关键字必须为bencoding字符串<br />值可以为任何bencoding编码类型<br />例如： d3:agei20ee 表示为{"age"=20}<br /> d4:path3:C:\8:filename8:test.txte 表示为{"path"="C:\","filename"="test.txt"}</p>
		<p>具体文件结构如下：<br />全部内容必须都为bencoding编码类型。<br />整个文件为一个字典结构,包含如下关键字<br />announce:tracker服务器的URL(字符串)<br />announce-list(可选):备用tracker服务器列表(列表)<br />creation date(可选):种子创建的时间，Unix标准时间格式，从1970 1月1日 00:00:00到创建时间的秒数(整数)<br />comment(可选):备注(字符串)<br />created by(可选):创建人或创建程序的信息(字符串)<br />info:一个字典结构，包含文件的主要信息，为分二种情况：单文件结构或多文件结构<br />单文件结构如下：<br />          length:文件长度，单位字节(整数)<br />          md5sum(可选)：长32个字符的文件的MD5校验和，BT不使用这个值，只是为了兼容一些程序所保留!(字符串)<br />          name:文件名(字符串)<br />          piece length:每个块的大小，单位字节(整数)<br />          pieces:每个块的20个字节的SHA1 Hash的值(二进制格式)<br />多文件结构如下：<br />          files:一个字典结构<br />                 length:文件长度，单位字节(整数)<br />                 md5sum(可选):同单文件结构中相同<br />                 path:文件的路径和名字，是一个列表结构，如\test\test.txt 列表为l4:test8test.txte<br />          name:最上层的目录名字(字符串)<br />          piece length:同单文件结构中相同<br />          pieces:同单文件结构中相同 <br />实例：<br />用记事本打开一个.torrent可以看来类似如下内容<br />d8:announce35:http://www.manfen.net:7802/announce13:creation datei1076675108e4:infod6:lengthi17799e4:name62:MICROSOFT.WINDOWS.2000.AND.NT4.SOURCE.CODE-SCENELEADER.torrent12:piece lengthi32768e6:pieces20:?W &#x6;?躐?緕排T酆ee</p>
		<p>很容易看出<br />announce＝<a href="http://www.chinaitpower.com/A/2002-03-25/&quot;http://www.manfen.net:7802/announce&quot;">http://www.manfen.net:7802/announce</a><br />creation date＝1076675108秒(02/13/04 20:25:08)<br />文件名=MICROSOFT.WINDOWS.2000.AND.NT4.SOURCE.CODE-SCENELEADER.torrent<br />文件大小＝17799字节<br />文件块大小＝32768字节<br /></p>
<img src ="http://www.blogjava.net/huyi2006/aggbug/241632.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/huyi2006/" target="_blank">allic</a> 2008-11-20 14:08 <a href="http://www.blogjava.net/huyi2006/articles/241632.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>