<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<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>清风的blog</title><link>http://blog.0451sky.com/</link><description>悠然探索，悠然索取</description><generator>RainbowSoft Studio Z-Blog 1.8 Spirit Build 80722</generator><language>zh-CN</language><copyright>Copyright (C) 2008-2010 0451sky.com Inc.,All  Rights Reserved.                    雅虎统计      </copyright><pubDate>Wed, 28 Jul 2010 22:22:26 +0800</pubDate><item><title>行转列1</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/295.html</link><pubDate>Wed, 28 Jul 2010 22:22:14 +0800</pubDate><guid>http://blog.0451sky.com/post/295.html</guid><description><![CDATA[<p>declare @sql varchar(8000)<br />set @sql = 'select 姓名 '<br />select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'<br />from (select distinct 课程 from tb) as a<br />set @sql = @sql + ' from tb group by 姓名'<br />print @SQL<br />exec(@sql)</p><p><br />select <br />(select UserName From SkyUser Where SkyUser.UserID=SkyEvaluationVD.UserID) UserID,<br />(select DetailName From SkyEvaluationDetail Where SkyEvaluationDetail.EvaluationID=SkyEvaluationVD.EName) EName<br />,EValue From SkyEvaluationVD</p><p>&nbsp;</p><p>declare @sql varchar(8000);<br />set @sql = 'select EName'<br />select @sql = @sql + ' , max(case UserID when ''' + UserID + ''' then Evalue else 0 end) [' + UserID + ']'<br />from (select distinct UserID from SkyEvaluationVD) as a<br />set @sql = @sql + ' from SkyEvaluationVD group by EName'<br />print @SQL<br />exec(@sql)</p><p><br />create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)<br />insert into tb values('张三' , '语文' , 74)<br />insert into tb values('张三' , '数学' , 83)<br />insert into tb values('张三' , '物理' , 93)<br />insert into tb values('李四' , '语文' , 74)<br />insert into tb values('李四' , '数学' , 84)<br />insert into tb values('李四' , '物理' , 94)<br />go</p><p>--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)<br />select 姓名 as 姓名 ,<br />&nbsp; max(case 课程 when '语文' then 分数 else 0 end) 语文,<br />&nbsp; max(case 课程 when '数学' then 分数 else 0 end) 数学,<br />&nbsp; max(case 课程 when '物理' then 分数 else 0 end) 物理<br />from tb<br />group by 姓名<br />&nbsp;</p>]]></description><category>技术文章</category><comments>http://blog.0451sky.com/post/295.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=295</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=295&amp;key=929f472e</trackback:ping></item><item><title>行转列</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/294.html</link><pubDate>Wed, 28 Jul 2010 22:21:23 +0800</pubDate><guid>http://blog.0451sky.com/post/294.html</guid><description><![CDATA[<p>Select *,<br />(select DetailName From SkyEvaluationDetail Where <br />SkyEvaluationDetail.EvaluationID=adc.EName) EName1<br />&nbsp;from (<br />select EName , max(case UserID when '1001' then Evalue else 0 end) [1001] , max(case UserID when '1002' then Evalue else 0 end) [1002] , max(case UserID when '1003' then Evalue else 0 end) [1003] from (select UserID,EName,Sum(EValue)/Count(*) as EValue <br />from SkyEvaluationVD Where EValue&lt;&gt;-10000 Group By UserID,EName) cccc group by EName) adc</p><p>&nbsp;</p>]]></description><category>技术笔记</category><comments>http://blog.0451sky.com/post/294.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=294</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=294&amp;key=0bc1fc2e</trackback:ping></item><item><title>普通行列转换</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/293.html</link><pubDate>Wed, 28 Jul 2010 21:12:35 +0800</pubDate><guid>http://blog.0451sky.com/post/293.html</guid><description><![CDATA[<p>/*<br />标题：普通行列转换(version 2.0)<br />作者：爱新觉罗.毓华 <br />时间：2008-03-09<br />地点：广东深圳<br />说明：普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法，version 2.0增加sql server 2005的有关写法。</p><p>问题：假设有张学生成绩表(tb)如下:<br />姓名 课程 分数<br />张三 语文 74<br />张三 数学 83<br />张三 物理 93<br />李四 语文 74<br />李四 数学 84<br />李四 物理 94<br />想变成(得到如下结果)： <br />姓名 语文 数学 物理 <br />---- ---- ---- ----<br />李四 74&nbsp;&nbsp; 84&nbsp;&nbsp; 94<br />张三 74&nbsp;&nbsp; 83&nbsp;&nbsp; 93<br />-------------------<br />*/</p><p>create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)<br />insert into tb values('张三' , '语文' , 74)<br />insert into tb values('张三' , '数学' , 83)<br />insert into tb values('张三' , '物理' , 93)<br />insert into tb values('李四' , '语文' , 74)<br />insert into tb values('李四' , '数学' , 84)<br />insert into tb values('李四' , '物理' , 94)<br />go</p><p>--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)<br />select 姓名 as 姓名 ,<br />&nbsp; max(case 课程 when '语文' then 分数 else 0 end) 语文,<br />&nbsp; max(case 课程 when '数学' then 分数 else 0 end) 数学,<br />&nbsp; max(case 课程 when '物理' then 分数 else 0 end) 物理<br />from tb<br />group by 姓名</p><p>--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)<br />declare @sql varchar(8000)<br />set @sql = 'select 姓名 '<br />select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'<br />from (select distinct 课程 from tb) as a<br />set @sql = @sql + ' from tb group by 姓名'<br />exec(@sql)</p><p>--SQL SERVER 2005 静态SQL。<br />select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b</p><p>--SQL SERVER 2005 动态SQL。<br />declare @sql varchar(8000)<br />select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程<br />exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')</p><p>---------------------------------</p><p>/*<br />问题：在上述结果的基础上加平均分，总分，得到如下结果：<br />姓名 语文 数学 物理 平均分 总分 <br />---- ---- ---- ---- ------ ----<br />李四 74&nbsp;&nbsp; 84&nbsp;&nbsp; 94&nbsp;&nbsp; 84.00&nbsp; 252<br />张三 74&nbsp;&nbsp; 83&nbsp;&nbsp; 93&nbsp;&nbsp; 83.33&nbsp; 250<br />*/</p><p>--SQL SERVER 2000 静态SQL。<br />select 姓名 姓名,<br />&nbsp; max(case 课程 when '语文' then 分数 else 0 end) 语文,<br />&nbsp; max(case 课程 when '数学' then 分数 else 0 end) 数学,<br />&nbsp; max(case 课程 when '物理' then 分数 else 0 end) 物理,<br />&nbsp; cast(avg(分数*1.0) as decimal(18,2)) 平均分,<br />&nbsp; sum(分数) 总分<br />from tb<br />group by 姓名</p><p>--SQL SERVER 2000 动态SQL。<br />declare @sql varchar(8000)<br />set @sql = 'select 姓名 '<br />select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'<br />from (select distinct 课程 from tb) as a<br />set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'<br />exec(@sql)</p><p>--SQL SERVER 2005 静态SQL。<br />select m.* , n.平均分 , n.总分 from<br />(select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,<br />(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n<br />where m.姓名 = n.姓名</p><p>--SQL SERVER 2005 动态SQL。<br />declare @sql varchar(8000)<br />select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程<br />exec ('select m.* , n.平均分 , n.总分 from<br />(select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m , <br />(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n<br />where m.姓名 = n.姓名')</p><p>drop table tb&nbsp;&nbsp;&nbsp;</p><p>------------------<br />------------------</p><p>/*<br />问题：如果上述两表互相换一下：即表结构和数据为：<br />姓名 语文 数学 物理<br />张三 74　　83　　93<br />李四 74　　84　　94<br />想变成(得到如下结果)： <br />姓名 课程 分数 <br />---- ---- ----<br />李四 语文 74<br />李四 数学 84<br />李四 物理 94<br />张三 语文 74<br />张三 数学 83<br />张三 物理 93<br />--------------<br />*/</p><p>create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)<br />insert into tb values('张三',74,83,93)<br />insert into tb values('李四',74,84,94)<br />go</p><p>--SQL SERVER 2000 静态SQL。<br />select * from<br />(<br />&nbsp;select 姓名 , 课程 = '语文' , 分数 = 语文 from tb <br />&nbsp;union all<br />&nbsp;select 姓名 , 课程 = '数学' , 分数 = 数学 from tb<br />&nbsp;union all<br />&nbsp;select 姓名 , 课程 = '物理' , 分数 = 物理 from tb<br />) t<br />order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end</p><p>--SQL SERVER 2000 动态SQL。<br />--调用系统表动态生态。<br />declare @sql varchar(8000)<br />select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'<br />from syscolumns <br />where name! = N'姓名' and ID = object_id('tb') --表名tb，不包含列名为姓名的其它列<br />order by colid asc<br />exec(@sql + ' order by 姓名 ')</p><p>--SQL SERVER 2005 动态SQL。<br />select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t</p><p>--SQL SERVER 2005 动态SQL，同SQL SERVER 2000 动态SQL。</p><p>--------------------<br />/*<br />问题：在上述的结果上加个平均分，总分，得到如下结果：<br />姓名 课程&nbsp;&nbsp; 分数<br />---- ------ ------<br />李四 语文&nbsp;&nbsp; 74.00<br />李四 数学&nbsp;&nbsp; 84.00<br />李四 物理&nbsp;&nbsp; 94.00<br />李四 平均分 84.00<br />李四 总分&nbsp;&nbsp; 252.00<br />张三 语文&nbsp;&nbsp; 74.00<br />张三 数学&nbsp;&nbsp; 83.00<br />张三 物理&nbsp;&nbsp; 93.00<br />张三 平均分 83.33<br />张三 总分&nbsp;&nbsp; 250.00<br />------------------<br />*/</p><p>select * from<br />(<br />&nbsp;select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb <br />&nbsp;union all<br />&nbsp;select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb<br />&nbsp;union all<br />&nbsp;select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb<br />&nbsp;union all<br />&nbsp;select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb<br />&nbsp;union all<br />&nbsp;select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb<br />) t<br />order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end</p><p>drop table tb<br />&nbsp;</p>]]></description><category>学习收藏</category><comments>http://blog.0451sky.com/post/293.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=293</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=293&amp;key=9494db60</trackback:ping></item><item><title>ASP防止SQL注入</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/292.html</link><pubDate>Wed, 14 Jul 2010 13:21:38 +0800</pubDate><guid>http://blog.0451sky.com/post/292.html</guid><description><![CDATA[<p>function gosql</p><p>Dim Fy_Post,Fy_Get,Fy_In,Fy_Inf,Fy_Xh,Fy_db,Fy_dbstr,Kill_IP,WriteSql<br />Fy_In = &quot;'|;|and|(|)|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare&quot;<br />Kill_IP=True<br />WriteSql=True&nbsp;&nbsp; <br />'----------------------------------</p><p><br />Fy_Inf = split(Fy_In,&quot;|&quot;)<br />'--------POST部份------------------<br />If Request.Form&lt;&gt;&quot;&quot; Then<br />For Each Fy_Post In Request.Form<br />&nbsp;&nbsp; For Fy_Xh=0 To Ubound(Fy_Inf)<br />&nbsp;&nbsp;&nbsp; If Instr(LCase(Request.Form(Fy_Post)),Fy_Inf(Fy_Xh))&lt;&gt;0 Then<br />&nbsp;&nbsp;&nbsp;&nbsp; If WriteSql=True Then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; killSqlconn.Execute(&quot;insert into SqlIn(Sqlin_IP,SqlIn_Web,SqlIn_FS,SqlIn_CS,SqlIn_SJ) values('&quot;&amp;Request.ServerVariables(&quot;REMOTE_ADDR&quot;)&amp;&quot;','&quot;&amp;Request.ServerVariables(&quot;URL&quot;)&amp;&quot;','POST','&quot;&amp;Fy_Post&amp;&quot;','&quot;&amp;replace(Request.Form(Fy_Post),&quot;'&quot;,&quot;''&quot;)&amp;&quot;')&quot;)<br />&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set killSqlconn = Nothing<br />&nbsp;&nbsp;&nbsp;&nbsp; End If<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;&lt;Script Language=JavaScript&gt;alert('SQL通用防注入系统提示你&darr;\n\n请不要在参数中包含非法字符尝试注入！\n');&lt;/Script&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;非法操作！系统做了如下记录&darr;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作ＩＰ：&quot;&amp;Request.ServerVariables(&quot;REMOTE_ADDR&quot;)&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作时间：&quot;&amp;Now&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作页面：&quot;&amp;Request.ServerVariables(&quot;URL&quot;)&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交方式：ＰＯＳＴ&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交参数：&quot;&amp;Fy_Post&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交数据：&quot;&amp;Request.Form(Fy_Post)<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.End<br />&nbsp;&nbsp;&nbsp; End If<br />&nbsp;&nbsp; Next<br />Next<br />End If<br />'----------------------------------</p><p>'--------GET部份-------------------<br />If Request.QueryString&lt;&gt;&quot;&quot; Then<br />For Each Fy_Get In Request.QueryString<br />&nbsp;&nbsp; For Fy_Xh=0 To Ubound(Fy_Inf)<br />&nbsp;&nbsp;&nbsp; If Instr(LCase(Request.QueryString(Fy_Get)),Fy_Inf(Fy_Xh))&lt;&gt;0 Then<br />&nbsp;&nbsp;&nbsp;&nbsp; If WriteSql=True Then<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp; End If<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;&lt;Script Language=JavaScript&gt;alert('SQL通用防注入系统提示你&darr;\n\n请不要在参数中包含非法字符尝试注入！\n');&lt;/Script&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;非法操作！系统做了如下记录&darr;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作ＩＰ：&quot;&amp;Request.ServerVariables(&quot;REMOTE_ADDR&quot;)&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作时间：&quot;&amp;Now&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;操作页面：&quot;&amp;Request.ServerVariables(&quot;URL&quot;)&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交方式：ＧＥＴ&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交参数：&quot;&amp;Fy_Get&amp;&quot;&lt;br&gt;&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write &quot;提交数据：&quot;&amp;Request.QueryString(Fy_Get)<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.End<br />&nbsp;&nbsp;&nbsp; End If<br />&nbsp;&nbsp; Next<br />Next<br />End If</p><p>end function</p><p>gosql</p>]]></description><category>技术文章</category><comments>http://blog.0451sky.com/post/292.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=292</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=292&amp;key=7f160fb8</trackback:ping></item><item><title>QQ通信协议</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/291.html</link><pubDate>Sun, 13 Jun 2010 13:49:34 +0800</pubDate><guid>http://blog.0451sky.com/post/291.html</guid><description><![CDATA[<p><br />QQ通讯协议<br />协议说明: <br />协议由报文头(T)+发送者(T)+接收者(T)+报文类型(T)+报文长度(L)+报文内容组成 <br />发送者和接收者是系统内的程序种类,OICQ服务器0x01,传真服务器0x02,WEB服务器0x03,打<br />印服务器是0x04,聊天服务器是0x05,OICQ用户是0x0A。 <br />OICQ用户到OICQ服务器的通讯协议引导符 (0x81+0x0A+0x01) <br />报文类型报文内容报文说明 <br />0x01 昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地区(T)+省(T<br />)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+电邮(S)+爱<br />好(S)+说明(S)+身份验证(T)新用户注册,身份验证用于当有人要将他加入好友时询问是否<br />允许 <br />0x02 服务号(L)+密码(S)+注册方式(T)老用户注册,方式分为0正常,1隐身 <br />0x03 服务号(L)+对方服务号(L)+内容(S) 发送信息到某人 <br />0x04 服务号(L)+组号(L)+内容(S) 广播信息,组号=0为全体 <br />0x05 服务号(L)+朋友服务号(L) 查看朋友资料 <br />0x06 服务号(L)+组名称(S) 增加组 <br />0x07 服务号(L)+组编号(T)+组名称(S) 修改组名称 <br />0x08 服务号(L)+组编号(T) 删除组 <br />0x09 服务号(L)+移动人数(T)+{朋友服务号(L)+目的组号(T)} 移动组成员 <br />0x0a 服务号(L)+起始编号(L)+回传个数(T)+查找标志(T) 看谁在线上 <br />查找标志 1=向小找 2=向大找 <br />0x0b 服务号(L)+SQL语句(S) 自定义查找 <br />0x0c 服务号(L)+朋友服务号(L) 增加好友 <br />0x0d 服务号(L)+朋友服务号(L)+加入原因(S) 请求加入好友 <br />0x0e 服务号(L)+朋友服务号(L) 删除好友 <br />0x10 服务号(L)+显示模式(T) 更改显示方式 1上线2隐藏3免打扰4离线 <br />0x11 服务号(L)+监视服务号(L) 监视某人谈话 <br />0x12 服务号(L)+昵称(S)+肖像(M)+用户密码(S)+性别(T)+年龄(T)+真实姓名(S)+国家/地<br />区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼(S)+<br />电邮(S)+爱好(S)+说明(S)+身份验证(T)更改用户基本信息 <br />0x13 服务号(L)+朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件 <br />0x14 服务号(L)+朋友服务号(L)+允许/拒绝是否允许发送文件 <br />0x15 服务号(L)+朋友服务号(L)+文件内容(B) 发送文件 <br />0x16 服务号(L) 连接测试报文 <br />0x17 服务号(L)+朋友服务号(L)+同意标志(T) 应答对方请求加入好友 <br />0=拒绝 <br />1=同意<br />OICQ服务器到OICQ的通讯协议 <br />报文类型报文内容报文说明 <br />0x01 成功/失败(T)+服务号(L) 新用户注册结果返回 <br />0x02 成功/失败(T)+组个数(T)+{组名称(S)+组编号(T)+朋友个数(T)+{朋友服务号(L)+肖<br />像编号(T)+朋友状态(T)+朋友昵称(S)] 老用户注册结果返回 <br />朋友状态 <br />1=上线=2隐藏=3免打扰4离线 <br />0x03 标志(T) + 朋友服务号(L)+信息(S)+信息类型(T) 标志 1=系统 2=用户 <br />发送消息,服务号=0是系统消息 <br />1=用户某某已经把你加为好友 <br />2=用户某某请求你通过身份验证 <br />3=用户某某同意了你的验证要求 <br />4=用户某某拒绝了你的验证请求 <br />0x04 成功/失败(T)+朋友服务号(L)+昵称(S)+肖像(M)+性别(T)+年龄(T)+真实姓名(S)+国<br />家/地区(T)+省(T)+市(S)+地址(S)+邮编(S)+学历(T)+毕业院校(S)+职业(T)+电话(S)+寻呼<br />(S)+电邮(S)+爱好(S)+说明(S)朋友信息回送 <br />0x05 成功/失败(T)+组编号(T)+组名称(S) 增加组结果回送 1/0 <br />0x06 成功/失败(T)+组编号(T)+组名称(S)修改组名称结果回送1/0 <br />0x07 成功/失败(T)+组编号(T) 删除组结果回送1/0 <br />0x08 成功/失败(T) 移动组成员结果回送1/0 <br />0x09 成功/失败(T)+在线个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)} 查找在线<br />人员结果回送 <br />0x0a 成功/失败(T)+找到个数(T)+{服务号(L)+昵称(S)+肖像(M)+省(T)+市(S)} 自定义查<br />找结果回送(最多50) <br />0x0b 标志(T)+朋友服务号(L) 增加好友结果回送标志 <br />0=数据库失败 <br />=1成功 <br />=2需要身份验证 <br />=3对方不允许加入 <br />=4需要身份验证且不在线 <br />0x0c 朋友服务号(L)+昵称(S)+肖像号(M)+朋友状态(T) 给在线用户增加好友 <br />0x0e 成功/失败(T)+朋友服务号(L) 删除好友结果回送 <br />0x10 服务号(L)+显示模式(T) 显示模式回送 =1上线=2隐藏=3免打扰4离线 <br />0x11 成功/失败更改用户基本信息结果回送 <br />0x12 朋友服务号(L)+文件名(S)+文件长度(L) 请求发送文件 <br />0x13 朋友服务号(L)+允许/拒绝是否允许发送文件 1允许 0拒绝 <br />0x14 朋友服务号(L)+文件内容(B) 发送文件 <br />0x15 朋友服务号(L)+当前状态(T)朋友状态回送(系统发送)=1上线=2隐藏=3免打扰4离线 <br />0x16 服务号(L) 连接测试</p><p>QQ协议网络协议--请求部份 <br />//登录 <br />VER=1.0&amp;CMD=Login&amp;SEQ=&amp;UIN=&amp;PS=&amp;M5=1&amp;LC=9326B87B234E7235 <br />//获取消息 <br />VER=1.0&amp;CMD=GetMsgEx&amp;SEQ=&amp;UIN= <br />//发送消息 <br />VER=1.0&amp;CMD=CLTMSG&amp;SEQ=&amp;UIN=&amp;UN=&amp;MG= <br />//朋友列表 <br />VER=1.0&amp;CMD=List&amp;SEQ=&amp;UIN=&amp;TN=160&amp;UN=0 <br />//获取好友状态 <br />VER=1.0&amp;CMD=Query_Stat&amp;SEQ=&amp;UIN=&amp;TN=50&amp;UN=0 <br />//获取好友信息 <br />VER=1.0&amp;CMD=GetInfo&amp;SEQ=&amp;UIN=&amp;LV=2&amp;UN= <br />//增加好友 <br />VER=1.0&amp;CMD=AddToList&amp;SEQ=&amp;UIN=&amp;UN= <br />//回应对方请求加你为好友的响应 <br />VER=1.0&amp;CMD=Ack_AddToList&amp;SEQ=&amp;UIN=&amp;UN=&amp;CD=&amp;RS= <br />//删除好友 <br />VER=1.0&amp;CMD=DelFromList&amp;SEQ=&amp;UIN=&amp;UN= <br />//搜索好友 <br />VER=1.0&amp;CMD=Finger&amp;SEQ=&amp;UIN=&amp;AG=&amp;SX=&amp;PV= <br />//改变自己状态，ST的代码应该和获取好友状态代码一致 <br />VER=1.0&amp;CMD=Change_Stat&amp;SEQ=&amp;UIN=&amp;ST= <br />//退出登录 <br />VER=1.0&amp;CMD=Logout&amp;SEQ=&amp;UIN=</p><p>基于HTTP的QQ协议之我所见 <br />--------------------------------------------------------------------------------<br />作者:未知 来源: 类别:**教程 日期:2005-06-19 今日/总浏览: 32/3203</p><p>有一年没有发表文章了,最近我为了一个项目对QQ协议进行研究,有些心得,不敢独享,故把其中一项协议-- <br />基于HTTP的QQ协议V1.1的不完整成果,拿出来与大家分享一下。 <br />大家说到QQ协议都觉得很神秘，是因为QQ不像MSN或者ICQ协议都已经官方公布了，而QQ的没有公布。研究 <br />它的人也不是特别的多，虽然已经有了基于QQ协议所写成的第三方软件 foicq, qq plugins for gaim, <br />LumaQQ，但是由于他们是基于二进制Stream的协议过于复杂，大家阅读代码也有一定的难度，再加上网络 <br />上解析QQ协议的文章也不是十分多，所以基于QQ网络协议的应用程序也是寥寥无几的。现在我就把基于HT <br />TP的QQ协议进行一个粗浅的剖析，希望对大家有所帮助。源码部分就用我喜欢的DELPHI和现在比较流行的 <br />C#语言对QQ协议的实现进行具体分析。 <br />1、找寻支持QQ HTTP协议的服务器。 <br />大家也许会被一些假像所迷惑，也许会认为QQ的HTTP服务器是基于80口进行通信的（如：218.17.209.23: <br />80），其实不然，正真基于HTTP的服务器应该是：<a href="http://tqq.tencent.com:8000">http://tqq.tencent.com:8000</a>，它是一个通过8000口 <br />进行通讯的服务器。 <br />由于QQ的HTTP服务器并不支持HTTP协议中GET方法，它支持POST方法。所以我们要给QQ的HTTP协议传参数 <br />，那么就必需要用POST方式才行。 <br />2、C#和DELPHI是实现HTTP的POST方法的通信。 <br />C#： <br />C#里System.Web空间下提供了一个叫做WebClient的对象，使用此对象就可以使C#直接对服务器发送WEB <br />客户端的请求。那么我们要对服务器提交POST方法那么就必须使用其UploadData()方法才行。首先把要请 <br />求的信息先转换为字节（因为POST提交的是字符的流数据），然后再做为UploadData()的参数。使用Uplo <br />adData()进行数据提交，最后返回，POST的回馈信息。如下： <br />WebClient _client = new WebClient(); <br />string postValues = &quot;VER=1.0&amp;CMD=Query_Stat&amp;SEQ=12321&amp;UIN=29501213&amp;TN=50&amp;UN=0&quot;; <br />Byte[] byteArray = System.Text.Encoding.ASCII.GetBytes(postValues); <br />Byte[] pageData = _client.UploadData(Host,&quot;POST&quot;,byteArray); <br />这样，我们就利用C#进行了一次HTTP的POST方法提交了。 <br />DELPHI： <br />Delphi里我们利用一个比较流行的第三方VCL，INDY HTTP（这个组件D6，D7里面自带）进行HTTP通信。 <br />使用其的POST方法便可以进行HTTP的POST通信，因为组件比较好用，我就不在其描述具体的过程了。大家 <br />可以参考以下代码： <br />function PostWebPage(url,para:String;TimeOut:Integer):String; <br />var <br />tmpWeb:TIdHTTP; <br />retrun:String; <br />Proxy:String; <br />i:Integer; <br />paralist:TStrings; <br />begin <br />retrun:=''; <br />try <br />&nbsp; paralist:=TStringList.Create; <br />&nbsp; paralist.Text:=_Replacing(para,'&amp;',#13#10); <br />&nbsp; tmpWeb:=TIdHTTP.Create(nil); <br />&nbsp; tmpWeb.ReadTimeout:=TimeOut; <br />&nbsp; for i:=1 to 3 do <br />&nbsp; begin <br />&nbsp;&nbsp;&nbsp; try <br />&nbsp;&nbsp;&nbsp; retrun:=tmpWeb.Post(url,paralist); <br />&nbsp;&nbsp;&nbsp; except end; <br />&nbsp;&nbsp;&nbsp; if retrun&lt;&gt;'' then break; <br />&nbsp; end; <br />finally <br />&nbsp;&nbsp;&nbsp; tmpWeb.Disconnect; <br />&nbsp;&nbsp;&nbsp; FreeAndNil(tmpWeb); <br />&nbsp;&nbsp;&nbsp; FreeAndNil(paralist); <br />end; <br />Result:=retrun; <br />end; <br />值在传入、返回时，其是基于UTF-8进行的，C#显示中文是很常，而DELPHI就要进行UTF-8的转换了。大家 <br />可通过Utf8ToAnsi()、AnsiToUtf8()进行转换。（编码转换是C#的优越性之一）</p><p>3、实现QQ的用户登录。 <br />在QQ通信中用户必需要登录后才可以进行互相发送信息等。QQ的登录是很关键的，大家所看到的用户在线 <br />，并不是用户的QQ一直连接着服务器，而是定时发送消信给服务器，证明自己还连着线，如果超出时间QQ <br />就认为用户已经掉线了。 <br />在登录协议中，QQ的密码是用标准的MD5来进行加密，DELPHI的用户只需要下个MD5加密模块就可以了，而 <br />C#自已带有，但是直接用不了，必需进行处理后，才能使其变成标准的MD5，处理代码如下： <br />&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static string MD5(string toCryString) <br />{ <br />&nbsp; MD5CryptoServiceProvider hashmd5; <br />&nbsp; hashmd5 = new MD5CryptoServiceProvider(); <br />&nbsp; return <br />BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace(&quot; <br />-&quot;,&quot;&quot;).ToLower();//asp是小写,把所有字符变小写 <br />} <br />了解QQ是如何对用户密码加密后，那么我们就开始真正，解析QQ的HTTP登录协议了,我们把协议当传POST <br />的参数传给服务器，而服务器则回馈相应的信息给客户端： <br />传入协议： <br />VER=1.1&amp;CMD=Login&amp;SEQ=&amp;UIN=&amp;PS=&amp;M5=1&amp;LC=9326B87B234E7235 <br />VER是用来说明QQ协议的版本，CMD是说明协议的命令，Login就是指QQ的登录了，SEQ是他的为了防止重 <br />复发送而设定的一个标记，一般我们取当前时间数值的一段放入即可。（C#：DateTime.Now.Ticks.ToStr <br />ing().Substring(7,7) DELPHI：CopyStr(inttostr(GetTickCount()),1,5)），UIN是说明你当前要登录 <br />的用户QQ号，PS，是MD5加密过后的密码的值。 <br />返回协议： <br />VER=1.1&amp;CMD=Login&amp;SEQ=11281&amp;UIN=&amp;RES=0&amp;RS=0&amp;HI=60&amp;LI=300（成功） <br />RES为0表示成功返回，RS为0表示登录成功。 <br />VER=1.1&amp;CMD=Login&amp;SEQ=11422&amp;UIN=315103947&amp;RES=0&amp;RS=1&amp;RA=登录失败 <br />RS为1表示登录失败，那么就会出现提示信息RA说明原因。 <br />4、获得QQ名单。 <br />如果您加了您的好友，那么您的好友就会放入你的QQ的好友名单里面，那么我们要得到QQ名单就必需给QQ <br />服务器发送得到好友名单的协议（我就不从复已知的参数了）： <br />VER=1.1&amp;CMD=List&amp;SEQ=&amp;UIN=&amp;TN=160&amp;UN=0 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=LIST&amp;SEQ=43661&amp;UIN=29501213&amp;RES=0&amp;FN=1&amp;SN=24&amp;UN=561256,1943497,.... <br />UN后面则是您好友的QQ号码，每个号码都由,进行分开。那么我们只需要得到UN后面的代码，把它列表化 <br />就OK了。C#可以用string.Split(',')把值放入列表进行处理，而DELPHI可以使用Split()把数值放入TStr <br />ings里进行处理。 <br />5、获得QQ好友在线名单 <br />获得QQ好友在线名单，跟获得好友名单差不多，唯一不同的是用的命令不同用的是Query_Stat，协议如下 <br />： <br />VER=1.1&amp;CMD=Query_Stat&amp;SEQ=&amp;UIN=&amp;TN=50&amp;UN=0 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=QUERY_STAT&amp;SEQ=-1&amp;UIN=29501213&amp;RES=0&amp;FC=141,270,270,&amp;FN=1&amp;SN=3&amp;ST=10,10,10,&amp;UN=1<br />2327207,24259132,29501213,&amp;NK= □,微程,鶹鸑,&amp; <br />FC为QQ头像的的ID，如的头像ID为270，那么其头使用的图片为91.bmp,其算法为ID/3+1。ST为QQ用户的状 <br />态，10为上线，20为离线，30为忙碌。UN为在线用户的QQ号，NK为在线用户的QQ昵称。ST，UN，NK，每个 <br />逗号隔开的数据相互对应。在得到消息后如果用的是DELPHI语言，那么要用Utf8ToAnsi()进行转换，不然 <br />会出现乱码。 <br />6、得到QQ用户的信息。 <br />如果要看到QQ用户的真实名称，MAIL，年龄，个人说明等信息，那么我们必需要向服务器发送得到好友信 <br />息的信息： <br />VER=1.1&amp;CMD=GetInfo&amp;SEQ=&amp;UIN=&amp;LV=2&amp;UN= <br />UN为要查看用户信息的QQ号。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=GETINFO&amp;SEQ=12707&amp;UIN=415103947&amp;RES=0&amp;AD=云南昆明<a href="mailto:&amp;AG=0&amp;EM=Microprogramer@hotmail">&amp;AG=0&amp;EM=Microprogramer@hotmail</a> <br />.com&amp;FC=270&amp;HP=msger.org(建设中...)&amp;JB=程序员&amp;LV=2&amp;PC=650000&amp;PH=0871-6466529&amp;PR=网络为媒%252 <br />c关系为本%252c信息为财%252c客户为主.%0d%0a&amp;PV=云南省&amp;RN=刘X&amp;SC=社会大学&amp;SX=0&amp;UN=24259132&amp;NK= <br />微程 <br />AD用户的联系地址，AG为用户年龄，EM为用户MAIL，FC为用户头像，HP为用户网站，JB为用户职业，PC为 <br />用户邮编，PH为用户联系电话，PR为用户简介，PV为用户所以的省，RN为用户真实名称，SC为用户毕业院 <br />校，SX为用户性别，UN为用户QQ号，NK为用户QQ昵称。在得到消息后如果用的是DELPHI语言，那么要用Ut <br />f8ToAnsi()进行转换，不然会出现乱码。 <br />7、增加QQ好友。 <br />想要新增好友，就要发送AddToList命令给服务器，具体命令如下： <br />VER=1.1&amp;CMD=AddToList&amp;SEQ=&amp;UIN=&amp;UN= <br />UN为我们要增加用户的QQ号。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=AddToList&amp;SEQ=13666&amp;UIN=415103947&amp;RES=0&amp;CD=0&amp;UN=24259132 <br />CD为被加QQ的身份验证状态，CD为0表示&ldquo;允许任何人把我列为好友&rdquo;，CD为1表示&ldquo;需要身份证认才能把 <br />我列为好友&rdquo;，CD为3表示&ldquo;不允许任何人把我列为好友&rdquo;。如果CD为0那么信息回馈后，用户就直接加为 <br />好友了，如果CD为1，那么还要发送一次回应加为好友的响应。 <br />8、回应加为好友的响应。 <br />回应加为好友响应是双方的：1、如果你发送了请求加对方为好友，如果对方需要验证，那么必需发送回 <br />应加为好友的响应。2、如果对方发送加为好友请求给你，那么你可以加应加为好友的响应，一是加为好 <br />友，一是通过验证，一是拒决加为好友。我们要向服务器发送命令： <br />VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=&amp;UIN=&amp;UN=&amp;CD=&amp;RS= <br />CD为响应状态，CD为0表示&ldquo;通过验证&rdquo;。CD为1表示&ldquo;拒决加为对方为好友&rdquo;。CD为2表示&ldquo;为请求对方 <br />加为好友&rdquo;。RS为你要请求的理由，如果您用的是DELPHI那么RS在发送之间要用AnsiToUtf8()进行转换， <br />不然发送过后，请求理由会变成&ldquo;？&rdquo;。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=Ack_AddToList&amp;SEQ=1130&amp;UIN=415103947&amp;RES=0&amp; <br />9、删除好友。 <br />删除好友其实很容易，向服务器发送DelFromList命令则可以删除用户： <br />VER=1.1&amp;CMD=DelFromList&amp;SEQ=&amp;UIN=&amp;UN= <br />UN为要删除用户的QQ号。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=DelFromList&amp;SEQ=24514&amp;UIN=415103947&amp;RES=0&amp; <br />10、改变用户当前状态。 <br />可以把QQ设置为在线，隐身等状态，我们可以发送Change_Stat给服务器以改变当前状态，具体命令如下 <br />： <br />VER=1.1&amp;CMD=Change_Stat&amp;SEQ=&amp;UIN=&amp;ST= <br />ST为要改变的状态，10为上线，20为离线，30为忙碌。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=Change_Stat&amp;SEQ=17512&amp;UIN=415103947&amp;RES=0&amp; <br />11、退出登录 <br />要退出登录，要向服务器发送命令Logout，具体命令如下： <br />VER=1.1&amp;CMD=Logout&amp;SEQ=&amp;UIN= <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=LOGOUT&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0 <br />12、获得好友QQ的消息 <br />如果要接收好友的消息，要向服务器发送命令GetMsgEx，具体命令如下： <br />VER=1.1&amp;CMD=GetMsgEx&amp;SEQ=&amp;UIN= <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=GETMSGEX&amp;SEQ=56661&amp;UIN=29501213&amp;RES=0&amp;MN=3&amp;MT=99,9,9,&amp;UN=24259132,24259132,24259 <br />132,&amp;MG=30 ,asdfasdfasdfasdf ,asdfasdfasdf ,&amp; <br />MT表示消息类型，99表示系统消息，9表示用户消息。UN表示消息发送来源用户，MG表示发送的消息，MG <br />消息可以表示某些特定的系统含意，譬如：当MT为99，MG为30，UN为24259132则表示用户4259132现在处 <br />于忙碌状态，可根据此消息进行好友列表的刷新，提高效率。在得到消息后如果用的是DELPHI语言，那么 <br />要用Utf8ToAnsi()进行转换，不然会出现乱码。 <br />13、向好友QQ发送消息 <br />要发送消息给好友，要向服务器发送命令CLTMSG命令，具体命令如下： <br />VER=1.1&amp;CMD=CLTMSG&amp;SEQ=&amp;UIN=&amp;UN=&amp;MG= <br />UN为消息发送给的用户QQ号码，MG为发送给该用户的消息。如果您用的是DELPHI那么MG在发送之间要用An <br />siToUtf8()进行转换，不然发送过后，消息会变成&ldquo;？&rdquo;。 <br />服务器得到协议后如果成功则返回： <br />VER=1.1&amp;CMD=CLTMSG&amp;SEQ=15803&amp;UIN=415103947&amp;RES=0 <br />好了，以上就是QQ基于HTTP的一个不完全的协议分析，在无源码前提下，在下能力有限，只能够分析这么 <br />多了。利用以上协议您就可以实现很多东西，如：QQ机器人，QQ广告系统，即时通讯的整合工具等等。</p>]]></description><category>学习收藏</category><comments>http://blog.0451sky.com/post/291.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=291</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=291&amp;key=cbb4d567</trackback:ping></item><item><title>快信连接服务器IP</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/290.html</link><pubDate>Sat, 12 Jun 2010 15:02:05 +0800</pubDate><guid>http://blog.0451sky.com/post/290.html</guid><description><![CDATA[<p><a href="http://221.130.45.201/">http://221.130.45.201/</a></p><p><a href="http://221.176.31.39:8080/">http://221.176.31.39:8080/</a></p>]]></description><category>学习收藏</category><comments>http://blog.0451sky.com/post/290.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=290</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=290&amp;key=319fd590</trackback:ping></item><item><title>QQ通信原理概述</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/289.html</link><pubDate>Sat, 12 Jun 2010 15:01:48 +0800</pubDate><guid>http://blog.0451sky.com/post/289.html</guid><description><![CDATA[<p>QQ通信原理概述<br />QQ通信原理概述一、登陆。<br />&nbsp; <br />&nbsp;&nbsp;&nbsp; 不管UDP还是TCP，最终登陆成功之后，QQ都会有一个TCP连接来保持在线状态。这个TCP连接的远程端口一般是80，采用UDP方式登陆的时候，端口是8000。因此，假如你所在的网络开放了80端口（80端口是最常用端口。。就是通常访问Web的端口，禁掉它的话，你的网络对你来说价值已经不大了），但没有屏蔽腾讯的服务器IP，恭喜你，你是可以登陆成功QQ的。<br />二、聊天消息通信。</p><p>&nbsp;&nbsp;&nbsp; 采用UDP协议，通过服务器中转方式。因此，现在的IP侦探在你仅仅跟对方发送聊天消息的时候是无法获取到IP的。大家都知道，UDP 协议是不可靠协议，它只管发送，不管对方是否收到的，但它的传输很高效。但是，作为聊天软件，怎么可以采用这样的不可靠方式来传输消息呢？于是，腾讯采用了上层协议来保证可靠传输：如果客户端使用UDP协议发出消息后，服务器收到该包，需要使用UDP协议发回一个应答包。如此来保证消息可以无遗漏传输。之所以会发生在客户端明明看到&ldquo;消息发送失败&rdquo;但对方又收到了这个消息的情况，就是因为客户端发出的消息服务器已经收到并转发成功，但客户端由于网络原因没有收到服务器的应答包引起的。</p><p>三、文件/自定义表情传送。</p><p>&nbsp;&nbsp;&nbsp; 大家都知道，QQ可以传送文件，可以发送自定义表情。先说官方表情。官方表情实际发送的是命令字，而没有发送表情。客户端收到命令字后，会自动解释为对应的表情。因此，QQ2008正式版的客户端发出的新版表情，在2007beta4及以前的版本无法找到相对应的表情，就无法解释，看到的就会是空白信息，但查聊天记录就会有[表情]字样。<br />&nbsp;&nbsp;&nbsp; 自定义表情的传送是以文件传输方式进行的。<br />&nbsp;&nbsp;&nbsp; 下面说文件传输方式：A要向B发送一个文件，于是发出一个文件传送请求。服务器收到这个文件传送请求后，转发给B，同时或者在B应答后，将A的IP地址同时发送给B。B这个时候就得到了A的真实IP。这里的IP是你的本机IP。也就是说，如果A处在内网，B得到的地址就是一个内网地址。B得到了A的地址之后，就会尝试去连接A。如果B也处于内网，那么，显然A跟B之间的连接是无法建立的。这个时候，客户端就会请求服务器进行文件中转。因为服务器具有公网 IP，处在内网的A跟B都是可以连接到服务器的，于是，A跟B的文件传送就通过服务器中转的方式，顺利进行。（注：服务器文件中转使用443端口）</p><p>*&nbsp;&nbsp; 注:什么是内网、公网<br />&nbsp;&nbsp;&nbsp; 内网、公网是两种Internet的接入方式。<br />&nbsp;&nbsp;&nbsp; 内网接入方式：上网的计算机得到的IP地址是Inetnet上的保留地址，保留地址有如下3种形式：<br />&nbsp;&nbsp;&nbsp; 10.x.x.x<br />&nbsp;&nbsp;&nbsp; 172.16.x.x至172.31.x.x<br />&nbsp;&nbsp;&nbsp; 192.168.x.x<br />&nbsp;&nbsp;&nbsp; 内网的计算机以NAT（网络地址转换）协议，通过一个公共的网关访问Internet。<br />&nbsp;&nbsp;&nbsp; 内网的计算机可向Internet上的其他计算机发送连接请求，但Internet上其他的计算机无法向内网的计算机发送连接请求。<br />&nbsp;&nbsp;&nbsp; 公网接入方式：上网的计算机得到的IP地址是Inetnet上的非保留地址。公网的计算机和Internet上的其他计算机可随意互相访问。</p><p>&nbsp;&nbsp;&nbsp; 所以,如果一个局域网只开放80端口，QQ是可以登陆成功的，也可以进行聊天。但传送文件也是不可以的，除非你们都在同一个内网。如果局域网还同时开放443端口，那么，恭喜你，QQ的功能你都可以正常使用。</p><p><br />QQ是不是TCP和UDP一起用?如果用UDP,如何做到信息的可靠发送? <br />答Q即可以使用TCP也可以使用UDP,但QQ默认是使用UDP协议,因为UDP协议消耗资源小,发送速度快,但当UDP协议不能正常转发的时候,就会采用TCP协议进行发送. <br />而信息的可靠发送是通过各种验证机制来完成的,这一点你可以去GOOGLE之类的网站去搜索下.</p><p>QQ用的是UDP打洞技术还是HTTP遂道? <br />答:发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服务器,只不过不是常用的那些,那个服务器是TX自行开发的</p><p>因为用户一般都是在局域网内,地址都为私有IP,IM服务器是如何将信息转发到用户的? <br />答:如果使用TCP就没什么好说了~由内网向外网连接,只要能够连接上进行握手了,消息就可以畅通无阻的进行发送了.如果使用UDP的话,就是使用的打洞技术了,只要通道打通了,发送消息基本和TCP没什么区别,要做的只是维护消息的完整性而已.</p><p><br />QQ是一个基于TCP/UDP协议的通讯软件，而MSN是基于TCP协议的通讯软件。</p><p>那么QQ是如何通讯的呢？在TCP/IP协议中，唯一标识一个应用进程的是socket，它通过网络层的IP地址和传输层的端口号来实现，对与同一个IP地址的内部网络，通过不同的端口号来标识不同的QQ进程；当你登陆QQ游戏服务器的时候，服务器会保留你的保留IP地址和端口号信息，并在你的好友的QQ进程中进行列表显示，然后两个进程就可以通信了。 <br />　　通常，发送文件的计算机首先要通过消息服务器将其IP地址发送给接收计算机，当接收计算机同意接收的确认消息反馈到消息服务器后，消息服务器将据此设置好文件传输对话。随即，发送计算机与接收计算机就会在确定好的端口范围内，建立起TCP或UDP连接开始文件的检索与传输。 <br />　　在默认状态下，QQ优先采用了UDP（User Data Protocol，用户数据报协议）协议传送数据，而对可靠性要求高的数据通讯系统往往使用TCP协议传输数据。与TCP协议不同，UDP协议并不提供数据传送的验证机制&mdash;&mdash;在整个文件传输过程中如果出现数据报的丢失，协议本身并不能作出任何的检测或提示。因此，通常人们把UDP协议称为不可靠的传输协议。 <br />　　UDP协议适用于无须应答、要求时效的软件使用，这样的设计正好与QQ追求的目标相符，所以QQ优先使用了此协议进行一切功能应用。但是，由于　　UDP协议具有不可靠性，常会因种种原因导致消息或数据的发送失败（很多时候会发现发送文件给对方接收时，对方根本收不到要求接收文件的消息。或是发送聊天消息时，对方根本没有收到过消息）。显然，UDP协议由于排除了信息可靠传递机制，将安全和排序等功能移交给上层应用来完成，极大降低了执行时间，使速度得到了保证。QQ在数据传输上更注重实际性能，为了获得更好的使用效果，往往可以牺牲一定的可靠性。因此，使用QQ来传输数据，在很多时候就成了一个&ldquo;不错&rdquo;的选择。 <br />　　一般内网传输首选QQ，速度最快，QQ的文件传输是直接个人对个人，采用P2P的传输方式，具有不需中转的优势，而且服务器都在国内，传输性能要高于外国IM软件。 <br />&nbsp;</p>]]></description><category>学习收藏</category><comments>http://blog.0451sky.com/post/289.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=289</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=289&amp;key=cff4d068</trackback:ping></item><item><title>悠索科技绩效考核系统v3.3</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/288.html</link><pubDate>Sun, 30 May 2010 22:53:26 +0800</pubDate><guid>http://blog.0451sky.com/post/288.html</guid><description><![CDATA[<p>########################################################<br />'-悠索科技绩效考核系统v3.3<br />'-官方网站：<a href="http://www.careff.com">http://www.careff.com</a><br />'-测试地址：<a href="http://kpi.0451sky.com">http://kpi.0451sky.com</a><br />'-管理用户名：admin 密码：admin<br />'-QQ：380894045 279018395（茈yy垭）<br />'-E-mail:careff@139.com<br />'-源码种类：.Net办公自动化<br />'-下载地址：<a href="http://www.careff.com/download/careffkpi33.rar">http://www.careff.com/download/careffkpi33.rar</a><br />'-帮助手册：<a href="http://www.careff.com/download/careffkpihelp.pdf">http://www.careff.com/download/careffkpihelp.pdf</a><br />'-首页效果：<a href="http://www.careff.com/download/kpi.gif">http://www.careff.com/download/kpi.gif</a><br />'-文件大小：4800KB<br />########################################################</p><p><br />悠索科技绩效考核系统(企业关键业绩考核系统)是黑龙江悠索工作室开发的产品。本系统采用.Net2008 开发，数据库基于Access/SQL2000/2005/2008 引擎开发。系统运行环境为.NET2.0+IIS6.0 基础环境。系统功能主要特色是可以自建部门，科室、员工信息。评估指标的项目和分数可以通过后台进行设置，您可以随便根据自己的需求进行定义。可以批量评价员工信息，不同的角色可以使用不同的评估指标进行评价。评估后的数据可以采用FLASH技术以图表的格式显示出来，方便使用的企业进行数据分析和数据挖掘。相关的数据均可以导出EXCEL 文档，方便保存和打印。系统在边防站和公安部门内部测试运行良好。</p><p>系统主要功能特色：<br />1、采用先进的开发技术.Net2.0+AJAX 技术实现，安全稳定，运行速度快；<br />2、评估时间段的自定义，可以随意的增加和删除相关时间段；<br />3、部门可以自行定义，可以随意的增加和删除部门信息；<br />4、科室可以自行定义，可以随意的增加和删除科室信息；<br />5、角色可以自行定义，可以随意的增加和删除角色信息；<br />6、登陆日志和操作日志，记录系统的运行情况；<br />7、评价指标可以自行定义，指标和角色关联，评估不同的角色使用不同的指标；指标<br />的数量和内容完全自己定义；<br />8、文件管理功能，类似Windows 的资源管理器，方便管理各种资源；<br />9、用户管理功能方便，可以方便的查询用户信息，管理用户资料；<br />10、数据评估功能是本系统的重要特色，使用树结构显示部门信息，选择部门后使用图<br />片默认显示相关人员，可以批量选择人员后在进行批量的评价；已经评价的用户显示灰色，<br />不能在进行评价；<br />11、在进行评价的时候，可以查看到人员的名称，点击名称可以查看详细的人员信息，<br />防止评价错误；<br />12、评估查询方便，直接显示被评价人的总分，平均分，评价人数，可以查看详细的得<br />分情况，但是不能显示是谁评价的(考虑评价人的身份保密性，采用匿名功能)<br />13、可以把任何的列表信息保存成Excel 文件，方便存档；<br />14、数据报表采用Flash 技术，可以让您更方便的分析系统内人员的成绩信息。<br />如果系统功能不满足您的要求，可以联系我们进行改进。<br />15、留言反馈留言板功能，用户可以通过留言板和管理员以及其他用户进行交流。</p><p><br />正式版本安装需要购买虚拟主机或者自己的虚拟服务器。软件运行要求如下：<br />1、IIS6.0 或以上。（如何安装可以联系我们）<br />2、.Net2.0<br />3、数据库支持Access2003<br />4、AJAX1.0 可以不安装<br />5、Windows2000/2003Server(XP 有连接数限制，不赞成使用)<br />6、本软件不支持虚拟目录，请放到站点根目录下方可运行<br />正式用户的安装，我方提供首次免费安装服务</p><p>&nbsp;</p>]]></description><category>软件发布</category><comments>http://blog.0451sky.com/post/288.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=288</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=288&amp;key=6b92a38e</trackback:ping></item><item><title>不错的网站风格</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/287.html</link><pubDate>Sat, 15 May 2010 11:28:52 +0800</pubDate><guid>http://blog.0451sky.com/post/287.html</guid><description><![CDATA[<p><a href="http://www.ptmfmr.com/">http://www.ptmfmr.com/</a><br /><a href="http://www.zzjr.cn/xxzx/xbdt/">http://www.zzjr.cn/xxzx/xbdt/</a><br /><a href="http://www.sihs.cn/index.asp">http://www.sihs.cn/index.asp</a><br /><a href="http://www.cqsxsdx.com/news/">http://www.cqsxsdx.com/news/</a><br /><a href="http://www.xmfls.net/">http://www.xmfls.net/</a><br /><a href="http://www.tassyxx.com/">http://www.tassyxx.com/</a><br /><a href="http://www.ydes.net/">http://www.ydes.net/</a></p>]]></description><category>学习收藏</category><comments>http://blog.0451sky.com/post/287.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=287</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=287&amp;key=227b93c4</trackback:ping></item><item><title>123</title><author>a@b.com (admin)</author><link>http://blog.0451sky.com/post/286.html</link><pubDate>Mon, 29 Mar 2010 13:58:55 +0800</pubDate><guid>http://blog.0451sky.com/post/286.html</guid><description><![CDATA[<p><a href="http://www.yiqilai.com/">http://www.yiqilai.com/</a></p>]]></description><category>技术文章</category><comments>http://blog.0451sky.com/post/286.html#comment</comments><wfw:comment>http://blog.0451sky.com/</wfw:comment><wfw:commentRss>http://blog.0451sky.com/feed.asp?cmt=286</wfw:commentRss><trackback:ping>http://blog.0451sky.com/cmd.asp?act=tb&amp;id=286&amp;key=15875503</trackback:ping></item></channel></rss>
