﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>学习日记 &#187; net work</title>
	<atom:link href="https://www.softwareace.cn/?cat=16&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>https://www.softwareace.cn</link>
	<description>时刻想着为自己的产品多做一些对他好的事情</description>
	<lastBuildDate>Fri, 20 Mar 2026 06:58:28 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	
	<item>
		<title>post和get的区别</title>
		<link>https://www.softwareace.cn/?p=1531</link>
		<comments>https://www.softwareace.cn/?p=1531#comments</comments>
		<pubDate>Fri, 28 Oct 2016 03:40:00 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1531</guid>
		<description><![CDATA[1. get是从服务器上获取数据，post是向服务器传送数据。 2. get是把参数数据队列加到提交表单的AC [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>1. get是从服务器上获取数据，post是向服务器传送数据。<br />
2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中，值和表单内各个字段一一对应，在URL中可以看到。post是通过HTTP post机制，将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。<br />
3. 对于get方式，服务器端用Request.QueryString获取变量的值，对于post方式，服务器端用Request.Form获取提交的数据。<br />
4. get传送的数据量较小，不能大于2KB。post传送的数据量较大，一般被默认为不受限制。但理论上，IIS4中最大量为80KB，IIS5中为100KB。<br />
5. get安全性非常低，post安全性较高。但是执行效率却比Post方法好。</p>
<p>建议：<br />
1、get方式的安全性较Post方式要差些，包含机密信息的话，建议用Post数据提交方式；<br />
2、在做数据查询时，建议用Get方式；而在做数据添加、修改或删除时，建议用Post方式；</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1531</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IMAP命令学习</title>
		<link>https://www.softwareace.cn/?p=1503</link>
		<comments>https://www.softwareace.cn/?p=1503#comments</comments>
		<pubDate>Wed, 31 Aug 2016 10:11:26 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1503</guid>
		<description><![CDATA[前几天要做关于IMAP协议方面的东西，对IMAP协议的命令不熟，特别是FETCH命令的用法，不但网上很难找到， [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>前几天要做关于IMAP协议方面的东西，对IMAP协议的命令不熟，特别是FETCH命令的用法，不但网上很难找到，就是专业文章也很难找到。经过这两天 对一些书籍和RFC3501的深入学习，了解了一些关于IMAP4协议命令的用法，有了一点心得体会，现在拿出来，希望能给做方面东西的朋友们一点帮助。<br />
1．<br />
CREATE &lt;folder&gt;<br />
CREATE可以创建指定名字的新邮箱。邮箱名称通常是带路径的文件夹全名。（有些IMAP客户机使用邮件夹称呼新邮箱）<br />
C: A003 CREATE owatagusiam/                 /*创建一个新目录owatagusiam*/<br />
S: A003 OK CREATE completed<br />
C: A004 CREATE owatagusiam/blurdybloop<br />
/* 在创建的目录owatagusiam下创建一个名为blurdybloop 的邮箱，当然可以省略第一步，直接A004 CREATE owatagusiam/blurdybloop ，表示在新的目录owatagusiam 下创建了一个名为blurdybloop 的邮箱*/<br />
S: A004 OK CREATE completed</p>
<p>2．<br />
DELETE &lt;folder&gt;<br />
DELETE命令删除指定名字的文件夹。文件夹名字通常是带路径的文件夹全名，当邮箱被删除后，其中的邮件也不复存在。<br />
C: A683 DELETE blurdybloop<br />
S: A683 OK DELETE completed<br />
C: A684 DELETE foo<br />
S: A684 NO Name &#8220;foo&#8221; has inferior hierarchical names<br />
C: A685 DELETE foo/bar<br />
S: A685 OK DELETE Completed</p>
<p>3．<br />
RENAME &lt;old folder&gt;&lt;new folder&gt;<br />
RENAME命令可以修改文件夹的名称，它使用两个参数：当前邮箱名和新邮箱名，两个参数的命名符合标准路径命名规则。<br />
C: A683 RENAME blurdybloop sarasoop<br />
S: A683 OK RENAME completed<br />
C: A684 RENAME stuff/junk newbox         /*把stuff目录（文件夹）下的邮箱junk改名为newbox*/<br />
S: A684 OK RENAME Completed</p>
<p>4．<br />
LIST &lt;BASE&gt;&lt;template&gt;<br />
LIST命令用于列出邮箱中已有的文件夹，有点像操作系统的列目录命令，有两个参数，邮箱路径参数BASE：表示用户登陆目录；第二个参数template：表示希望显示的邮箱名。这个命令可以包含起始的路径位置和需要列出的文件夹所符合的特征，可以使用通配符&#8221;*&#8221;。<br />
C: A101 LIST &#8220;&#8221; &#8220;&#8221;<br />
S: * LIST (/Noselect) &#8220;/&#8221; &#8220;&#8221;<br />
S: A101 OK LIST Completed<br />
C: A102 LIST #news.comp.mail.misc &#8220;&#8221;<br />
S: * LIST (/Noselect) &#8220;.&#8221; #news.<br />
S: A102 OK LIST Completed<br />
C: A103 LIST /usr/staff/jones &#8220;&#8221;<br />
S: * LIST (/Noselect) &#8220;/&#8221; /<br />
S: A103 OK LIST Completed<br />
C: A202 LIST ~/Mail/ %<br />
S: * LIST (/Noselect) &#8220;/&#8221; ~/Mail/foo<br />
S: * LIST () &#8220;/&#8221; ~/Mail/meetings<br />
S: A202 OK LIST completed</p>
<p>5．<br />
APPEND &lt;folder&gt;&lt;attributes&gt;&lt;date/time&gt;&lt;size&gt;&lt;mail data&gt;<br />
APPEND命令允许Client上载一个邮件到指定的Folder（文件夹/邮箱）中。命令中包含了新邮件的属性、日期/时间、大小，随后是邮件数据。<br />
C: A003 APPEND saved-messages (/Seen) {310}<br />
C: Date: Mon， 7 Feb 1994 21:52:25 -0800 (PST)<br />
C: From: Fred Foobar &lt;<a style="color: #336699;" href="mailto:foobar@Blurdybloop.COM">foobar@Blurdybloop.COM</a> &gt;<br />
C: Subject: afternoon meeting<br />
C: To: <a style="color: #336699;" href="mailto:mooch@owatagu.siam.edu">mooch@owatagu.siam.edu</a><br />
C: Message-Id: &lt;<a style="color: #336699;" href="mailto:B27397-0100000@Blurdybloop.COM">B27397-0100000@Blurdybloop.COM</a> &gt;<br />
C: MIME-Version: 1.0<br />
C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII<br />
C:<br />
C: Hello Joe， do you think we can meet at 3:30 tomorrow?<br />
C:<br />
S: A003 OK APPEND completed</p>
<p>6．<br />
SELECT &lt;folder&gt;<br />
SELECT命令让Client选定某个邮箱（Folder），表示即将对该邮箱（Folder）内的邮件作操作。邮箱标志的当前状态也返回给了用户，同时返回的还有一些关于邮件和邮箱的附加信息。<br />
C: A142 SELECT INBOX<br />
S: * 172 EXISTS<br />
S: * 1 RECENT<br />
S: * OK [UNSEEN 12] Message 12 is first unseen<br />
S: * OK [UIDVALIDITY 3857529045] UIDs valid<br />
S: * FLAGS (/Answered /Flagged /Deleted /Seen /Draft)<br />
S: * OK [PERMANENTFLAGS (/Deleted /Seen /*)] Limited<br />
S: A142 OK [READ-WRITE] SELECT completed</p>
<p>7．<br />
FETCH &lt;mail id&gt;&lt;datanames&gt;<br />
FETCH 命令用于读取邮件的文本信息，且仅用于显示的目的。包含两个参数，messageset：表示希望读取的邮件号列表，IAMP服务器邮箱中的每个邮件都有 一个唯一的ID标识，（邮件号列表参数可以是一个邮件号，也可以是由逗号分隔的多个邮件号，或者由冒号间隔的一个范围），IMAP服务器返回邮件号列表中 全部邮件的指定数据项内容。<br />
数据名参数确定能够被独立返回的邮件的一部分，下面我们看看各参数返回的邮件信息：<br />
ALL：只返回按照一定格式的邮件摘要，包括邮件标志、RFC822.SIZE、自身的时间和信封信息。IMAP客户机能够将标准邮件解析成这些信息并显示出来。<br />
BODY：只返回邮件体文本格式和大小的摘要信息。IMAP客户机可以识别这些细腻，并向用户显示详细的关于邮件的信息。其实是一些非扩展的BODYSTRUCTURE的信息。<br />
FAST：只返回邮件的一些摘要，包括邮件标志、RFC822.SIZE、和自身的时间。<br />
FULL：同样的还是一些摘要信息，包括邮件标志、RFC822.SIZE、自身的时间和BODYSTRUCTURE的信息。<br />
BODYSTRUCTUR： 是邮件的[MIME-IMB]的体结构。这是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段和[MIME-IMB]头信息得出来 的。包括的内容有：邮件正文的类型、字符集、编码方式等和各附件的类型、字符集、编码方式、文件名称等等。<br />
ENVELOPE：信息的信封结构。是服务器通过解析[RFC-2822]头中的[MIME-IMB]各字段得出来的，默认各字段都是需要的。主要包括：自身的时间、附件数、收件人、发件人等。<br />
FLAGS：此邮件的标志。<br />
INTERNALDATE：自身的时间。<br />
RFC822.SIZE：邮件的[RFC-2822]大小<br />
RFC822.HEADER：在功能上等同于BODY.PEEK[HEADER]，<br />
RFC822：功能上等同于BODY[]。<br />
RFC822.TEXT：功能上等同于BODY[TEXT]<br />
UID：返回邮件的UID号，UID号是唯一标识邮件的一个号码。<br />
BODY[section] &lt;&lt;partial&gt;&gt;：返回邮件的中的某一指定部分，返回的部分用section来表示，section部分包含的信息通常是 代表某一部分的一个数字或者是下面的某一个部分：HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的话，那就代表返回全部的信息，包括头信息。<br />
BODY[HEADER]返回完整的文件头信息。<br />
BODY[HEADER.FIELDS ()]：在小括号里面可以指定返回的特定字段。<br />
BODY[HEADER.FIELDS.NOT ()]：在小括号里面可以指定不需要返回的特定字段。<br />
BODY[MIME]：返回邮件的[MIME-IMB]的头信息，在正常情况下跟BODY[HEADER]没有区别。<br />
BODY[TEXT]：返回整个邮件体，这里的邮件体并不包括邮件头。<br />
现在我们遇到了一个问题，如果我们要单独提取邮件的附件怎么办？<br />
通过以上的命令我们是无法做到的，但是我们别忘了在section部分还有其他的方式可以来表示我们要提取的邮件的部分，那就的通过区段数来表示。那下面就让我们来看看什么是区段数。<br />
每 个邮件都至少有一个区段数，Non-[MIME-IMB]型的邮件和non-multipart [MIME-IMB]的邮件是没有经过MIME编码之后的信息的，那这样的信息只有一个区段数1。多区段型的信息被编排成一个连续的区段数，这和实际信息 里出现的是一样的。如果一个特定的区段有类型信息或者是多区段的，一个MESSAGE/RFC822类型的区段也含有嵌套的区段数，这些区段数是指向这些 信息区段的信息体的。<br />
说了那么多拗口的，现在我们讲的更简单易懂一些。在一个邮件体里面，区段数1代表的邮件的正文，区段数二代表的是第一个附 件，区段数三代表的是第二个附件，以此类推。在这些区段里，如果有哪个区段又是多区段的，比如2区段的内容格式是mulipart或者是 MESSAGE/RFC822类型的，那么这个区段又嵌套了多个子区段，嵌套的各子区段是用2.1，2.2……等等表示，类似，如果2.1又有嵌套，那么 还会有2.1.1，2.1.2等区段。这样的嵌套是没有限制的。下面我们通过例子来了解一下fetch具体是怎么按区段下载的。<br />
HEADER ([RFC-2822] header of the message)<br />
TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED<br />
1 TEXT/PLAIN<br />
2 APPLICATION/OCTET-STREAM<br />
3 MESSAGE/RFC822<br />
3.HEADER ([RFC-2822] header of the message)<br />
3. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED<br />
3.1 TEXT/PLAIN<br />
3.2 APPLICATION/OCTET-STREAM<br />
4 MULTIPART/MIXED<br />
4.1 IMAGE/GIF<br />
4.1. MIME ([MIME-IMB] header for the IMAGE/GIF)<br />
4.2 MESSAGE/RFC822<br />
4.2. HEADER ([RFC-2822] header of the message)<br />
4.2. TEXT ([RFC-2822] text body of the message) MULTIPART/MIXED<br />
4.2.1 TEXT/PLAIN<br />
4.2.2 MULTIPART/ALTERNATIVE<br />
4.2.2.1 TEXT/PLAIN<br />
4.2.2.2 TEXT/RICHTEXT<br />
如果我们需要取第一个附件，那么命令就是：<br />
C:a2 fetch 4 body[2];<br />
取第三个区段的第一个子区段文本正文，命令就是：<br />
C:a2 fetch 4 body[3.1];<br />
取第四个区段的第二个子区段再嵌套的第一个子区段的文本正文，命令如下：<br />
C:a2 fetch 4 body[4.2.1]<br />
当然这个例子只是针对于一个特殊的邮件结构，一般的邮件应该都没有这么复杂的结构。<br />
再 接下来我们再看看最后一个参数有什么用？BODY[section]可以使用partial字段进行修改，该字段包含两个用“.”隔开的数字，第一个数 字、是八进制表示的希望显示的数据输出起始位置，第二个数字是八进制表示希望显示的数据长度。这项功能可以进一步设定输出格式，例如，如果你希望显示1号 邮件中邮件提的前1500个字符，可以使用命令：<br />
FETCH 1 BODY[TEXT]&lt;0.1500&gt;<br />
该命令取回邮件提的前1500个字符并定义为TEXT，如果邮件体少于1500个字符则返回整个邮件体。<br />
例：<br />
C: 100 FETCH 3：5  BODY[header.fields (Date From Subject)]  /*冒号表示间隔的一个范围：请求邮件从3到5之间所有邮件的Date：字段、 From：字段和 Subject：字段的信息*/<br />
S: *  3  FETCH  (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)]  {112}<br />
DATE: Tue, 14 Sep 1999 10:09:50 -500<br />
From: <a style="color: #336699;" href="mailto:alex@shadrach.smallorg.org">alex@shadrach.smallorg.org</a><br />
Subject: This is the first test message<br />
)<br />
S: *  4  FETCH  (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)]  {113}<br />
DATE: Tue, 14 Sep 1999 10:10:04 -500<br />
From: <a style="color: #336699;" href="mailto:alex@shadrach.smallorg.org">alex@shadrach.smallorg.org</a><br />
Subject: This is the second test message<br />
)<br />
S: *  5  FETCH  (BODY[HEADER.FIELDS (“DATE” “FROM” “SUBJECT”)]  {112}<br />
DATE: Tue, 14 Sep 1999 10:20:26 -500<br />
From: <a style="color: #336699;" href="mailto:alex@shadrach.smallorg.org">alex@shadrach.smallorg.org</a><br />
Subject: This is the first test message<br />
S: A100 OK FETCH completed<br />
C: A101 FETCH BODY[TEXT]<br />
S:* This is the fourth test message for IMAP<br />
S: A101 OK FETCH completed<br />
FETCH命令是IMAP协议里最复杂的命令。FETCH的命令参数很多、很复杂，但基本的特征是允许将邮件按照MIME结构拆解为零碎的部件来提取。例如，可以利用FETCH命令提取邮件头、某一个附件、或某一邮件附件头部的某一字段，等等。<br />
BODY.PEEK [&lt;section&gt;] &lt;&lt;partial&gt;&gt;：<br />
在 缺省设置时，宏BODY[&lt;section&gt;]&lt;&lt;partial&gt;&gt;会设置邮件的/SEEN标志。如果你想在不设 置/SEEN标志的情况下阅读邮件的部分信息，那么可以将该宏替代BODY .PEEK[section]，后者完成同前者一样的功能但不会设置该邮件的/SEEN标志。</p>
<p>8．<br />
STORE &lt;mail id&gt;&lt;new attributes&gt;<br />
STORE 命令用于修改指定邮件的属性，包括给邮件打上已读标记、删除标记，等等。STORE命令当前只有两个数据项类型可用，FLAGS：表示邮件的一组标志； FLAGS.SLIENT，表示一组邮件的标志，通过在两种数据项前加上加号或者减号可以进一步改变它们的执行情况，加号表示数据项的值添加到邮件中，减 号表示将数据项的值从邮件中删除。<br />
C: A003 STORE 2:4 +FLAGS (/Deleted)      /*冒号表示间隔的一个范围：给从2到4的邮件设置Deleted属性*/<br />
S: * 2 FETCH FLAGS (/Deleted /Seen)<br />
S: * 3 FETCH FLAGS (/Deleted)<br />
S: * 4 FETCH FLAGS (/Deleted /Flagged /Seen)<br />
S: A003 OK STORE completed</p>
<p>9．<br />
CLOSE<br />
CLOSE命令表示Client结束对当前Folder（文件夹/邮箱）的访问，关闭邮箱该邮箱中所有标志为、DELETED的邮件就被从物理上删除。CLOSE没有命令参数。随后可以SELECT另一Folder。<br />
C: A341 CLOSE<br />
S: A341 OK CLOSE completed</p>
<p>10．<br />
EXPUNGE<br />
EXPUNGE命令在不关闭邮箱的情况下删除所有的标志为、DELETED的邮件。EXPUNGE删除的邮件将不可以恢复。<br />
C: A202 EXPUNGE<br />
S: * 3 EXPUNGE<br />
S: * 3 EXPUNGE<br />
S: * 5 EXPUNGE<br />
S: * 8 EXPUNGE<br />
S: A202 OK EXPUNGE completed<br />
LOGOUT<br />
LOGOUT命令结束本次IMAP会话。<br />
C: A023 LOGOUT<br />
S: * BYE IMAP4rev1 Server logging out<br />
S: A023 OK LOGOUT completed<br />
(Server and client then close the connection)</p>
<p>11.<br />
EXAMINE &lt;mailbox&gt;<br />
EXAMINE命令以只读方式打开邮箱，参数是需要打开的邮箱的名字，使用EXAMINE命令打开的邮箱不允许对邮件进行改动，因此不能增加或删除邮件的标志。</p>
<p>12.<br />
SUBSCRIBE &lt;mailbox&gt;<br />
SUBSCRIBE命令用来在客户机的活动邮箱列表中增加一个邮箱，该命令只有一个参数，希望添加的邮箱名。<br />
C: A114 SUBSCRIBE new/anotherbox<br />
S: A114 OK SUBSCRIBE completed</p>
<p>13.<br />
UNSUBSCRIBE &lt;mailbox&gt;<br />
UNSUBSCRIBE命令用来从活动列表中去掉一个邮箱，一个参数：希望去掉的邮箱名。<br />
C: A115 UNSUBSCRIBE new/anotherbox<br />
S: A115 OK SUBSCRIBE completed</p>
<p>14.<br />
LSUB &lt;folder&gt;&lt;mailbox&gt;<br />
LSUB命令修正了LIST命令，LIST返回用户$HOME目录下所有的文件，但LSUB命令只显示那些使用SUBSCRIBE命令设置为活动邮箱的文件。两个参数：邮箱路径和邮箱名。<br />
C: A116 LSUB “” *<br />
S:* LSUB () “/” stuff/junk<br />
S:* LSUB () “/” neebox<br />
S:* LSUB () “/” new/anotherbox<br />
S: A116 OK LSUB completed</p>
<p>15.<br />
STATUS &lt;mailbox&gt;(&lt;parameter1&gt;  &lt; parameter2&gt;  ……&lt;parameter5&gt;)<br />
STATUS命令查询邮箱的当前状态。第一个参数是需要查询的邮箱名，第二个参数是客户机需要查询的项目列表（要查询显示的信息），当在圆括号中。STATUS可以在不使用SELECT命令（打开邮箱）或者EXAMINE（以只读方式打开邮箱）前提下获取邮箱的信息。<br />
STATUS命令可以获得的数据项<br />
项 目                 说  明<br />
MESSAGE         邮箱中的邮件总数<br />
RECENT         邮箱中标志为/RECENT的邮件数<br />
UIDNEXT         可以分配给新邮件的下一个UID<br />
UIDVALIDITY         邮箱的UID有效性标志<br />
UNSEEN         邮箱中没有被标志为/UNSEEN的邮件数<br />
C: A117 STATUS inbox  (message recent unseen)<br />
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 0)<br />
S: A117 OK STATUS completed<br />
C: A118 STATUS newbox  (message recent unseen)<br />
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 2)<br />
S: A118 OK STATUS completed</p>
<p>16.<br />
CHECK<br />
CHECK命令用来在邮箱设置一个检查点。没有参数。就是IMAP中的sync命令。任何未完成的操作，例如从服务器内存向硬盘写数据，都将会被做完以保持邮箱的一致性状态。该命令确保乃村中的磁盘缓冲数据都被写到了磁盘上。</p>
<p>17．<br />
SEARCH [CHARSET specification] (search criteria)<br />
命 令可以根据搜索条件在处于活动状态的邮箱中搜索邮件，然后显示匹配的邮件编号。字符集标志参数[CHARSET specification]由CHARSET和注册的字符集标志符组成，缺省的标志符是US-ASCⅡ，所以该参数长省略。search criteria：查询条件参数，明确查询的关键字和值。查询关键字有几十种。<br />
C: A119 SEARCH header subject another<br />
S: SEARCH 1 2<br />
S:* A119 OK SEARCH completed<br />
C: A120 SEARCH header subject another<br />
S: *SEARCH 2<br />
S: A120 OK SEARCH completed<br />
C: A121 SEARCH UNSEEN<br />
S: *SEARCH 1 2<br />
S: A120 OK SEARCH completed<br />
以上每个例子都在邮件头的Subject:字段中查询一个不同的单词。服务器返回条件的邮件号列表，如果没有匹配邮件则返回不带UID的SEARCH单词。</p>
<p>18.<br />
COPY &lt;mail id&gt;&lt;mailboxname&gt;<br />
COPY命令可以把邮件从一个邮箱复制到另一个邮箱，两个参数：mail id是希望从活动邮箱中复制的邮件的标号，mailboxname是希望邮件被复制到的邮箱。<br />
IAMP没有定义移动邮件的命令，移动操作相当于先把邮件复制到新邮箱中，然后对源邮箱中的邮件设置/DELETED标志。下一次执行检查点过后，新邮箱中的邮件被删除，新邮件就被显示出来。</p>
<p>19.<br />
UID<br />
UID 命令和FETCH、COPY、STORE命令或者SEARCH命令一起使用，它允许这些命令使用邮件的UID号而不是在邮箱中的顺序号。UID号是唯一标 识邮件系统中邮件的32位证书。通常这些命令都使用顺序号来标识邮箱中的邮件，使用UID可以使IMAP客户机记住不同IMAP会话中的邮件。</p>
<p>20.<br />
CAPABILITY<br />
CAPABILITY命令请求返回IMAP服务器支持的功能列表，服务器收到客户机发送的CAPABILITY命令后将返回该服务器所支持的功能。无参数。<br />
C: A122 CAPABILITY<br />
S:*A122 CAPABILITY IMAP4 IMAP4REVl NAMESPACE IDLE SCAN SORT   MAILBOX<br />
&#8211;REFERRALS [ic:ccc] LOGIN-REFERRALS AUTH=LOGIN THREAD=<br />
ORDERDSUBJECT<br />
S: A122 OK CAPABILITY completed</p>
<p>21.<br />
NOOP<br />
NOOP命令什么也不做，用来向服务器发送自动命令，防止因长时间处于不活动状态而导致连接中断，服务器对该命令的响应始终为肯定。无参数。</p>
<p>22.<br />
LOGOUT<br />
LOGOUT命令使当前登陆用户退出登陆并关闭所有打开的邮箱，任何做了/DELETED标志的邮件都将在这个时候被删除。</p>
<p>这里不是所有的命令都列出来了，没有列出来的命令如果需要的可以去参考RFC3501。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1503</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QWebView support SSL and Redirection</title>
		<link>https://www.softwareace.cn/?p=1295</link>
		<comments>https://www.softwareace.cn/?p=1295#comments</comments>
		<pubDate>Wed, 08 Apr 2015 09:22:43 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>
		<category><![CDATA[Qt Gui]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1295</guid>
		<description><![CDATA[[crayon-69fb66a909597640977281/] &#160; [crayon-69fb66a [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">#ifndef D_H
#define D_H

#include &lt;QtWidgets/QMainWindow&gt;
#include &lt;QtNetwork&gt;
#include "ui_d.h"
class d : public QMainWindow
{
	Q_OBJECT

public:
	d(QWidget *parent = 0);
	~d();

private:
	Ui::dClass ui;
	QNetworkRequest m_networkRequest;
private slots:
	void on_networkReply_finished(QNetworkReply* reply);
	void on_networkReply_sslErrors(QNetworkReply* reply, const QList&lt;QSslError&gt; &amp;errors);
};

#endif // D_H</pre><p>&nbsp;</p><pre class="crayon-plain-tag">#include "d.h"

d::d(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	if (!QSslSocket::supportsSsl())
		Q_ASSERT(!"no supportsSsl!! please install http://slproweb.com/products/Win32OpenSSL.html");
	QSslConfiguration configSsl = QSslConfiguration::defaultConfiguration();
	configSsl.setProtocol(QSsl::AnyProtocol);
	m_networkRequest.setSslConfiguration(configSsl);
	connect(ui.wbLogin-&gt;page()-&gt;networkAccessManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(on_networkReply_finished(QNetworkReply*)));
	connect(ui.wbLogin-&gt;page()-&gt;networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*, const QList&lt;QSslError&gt;&amp;)), this, 
		SLOT(on_networkReply_sslErrors(QNetworkReply*, const QList&lt;QSslError&gt;&amp;)));
}

d::~d()
{

}


void d::on_networkReply_finished(QNetworkReply* reply)
{
	if (reply-&gt;error() == QNetworkReply::NoError)
	{
		int statusCode = reply-&gt;attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
		if (statusCode == 301 || statusCode == 302)
		{
			QString strUrl = reply-&gt;attribute(QNetworkRequest::RedirectionTargetAttribute).toString();

			if (!strUrl.isEmpty())
			{
				if (strUrl.contains(SUCCESSED_MARK))
				{
					analysisUrl(strUrl);
				}
				else
				{
					m_networkRequest.setUrl(QUrl(strUrl));
					ui.wbLogin-&gt;load(m_networkRequest);
				}
			}
			if (reply)
			{
				reply-&gt;close();
				reply = NULL;
			}
			return;
		}
		else
		{
			QString imageData = reply-&gt;readAll();

		}
	}
	else
	{
		QString error = reply-&gt;errorString();
		QMessageLogger(__FILE__, __LINE__, 0).warning() &lt;&lt; error;
	}

	if (reply)
	{
		reply-&gt;close();
		reply = NULL;
	}
}

void d::on_networkReply_sslErrors(QNetworkReply* reply, const QList&lt;QSslError&gt; &amp;errors)
{
	foreach(QSslError e, errors)
	{
		Q_ASSERT(!"SslErrors");
		QMessageLogger(__FILE__, __LINE__, 0).warning() &lt;&lt; e.errorString();
	}
	reply-&gt;ignoreSslErrors();
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1295</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用WinInet远程下载文件的示例代码</title>
		<link>https://www.softwareace.cn/?p=1133</link>
		<comments>https://www.softwareace.cn/?p=1133#comments</comments>
		<pubDate>Thu, 29 Jan 2015 01:08:55 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1133</guid>
		<description><![CDATA[[crayon-69fb66a90a2b8599573337/] &#160;]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">#include&lt;windows.h&gt;   
#include&lt;wininet.h&gt;   
#include&lt;iostream&gt; 
#include &lt;tchar.h&gt;
using namespace std;
 
#pragma comment(lib,"wininet.lib")   
void main()   
{   
    DWORD byteread=0;   
    char buffer[100];   
    memset(buffer,0,100);   
    HINTERNET internetopen;   
 
    internetopen = InternetOpen(/*_T("DownLoadFile")*/NULL,INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);   
    if (internetopen==NULL)   
    {    
        cout&lt;&lt;"Internet open failed!"&lt;&lt;endl;   
        return;   
    }   
 
    HINTERNET    internetopenurl;   
    internetopenurl = InternetOpenUrl(internetopen,_T("http://topic.csdn.net/u/20090429/10/6a38f59f-b776-4140-a11b-f59c4a979931.html"),
        NULL,0,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_PRAGMA_NOCACHE,0);      //下载的URL
    if (internetopenurl==NULL)   
    {    
        cout&lt;&lt;"Internet open url failed! error code = "&lt;&lt;GetLastError()&lt;&lt;endl;    
        goto there;   
    }   
 
    BOOL hwrite;   
    DWORD written;   
    HANDLE createfile;   
    createfile = CreateFile(_T("c://downloaded.html"),GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);  //保存文件 
    if (createfile==INVALID_HANDLE_VALUE)   
    {     
        cout&lt;&lt;"Create File failed!"&lt;&lt;endl;   
        goto next;   
    }   
    BOOL internetreadfile;   
    while(1)   
    {   
        internetreadfile=InternetReadFile(internetopenurl,buffer,sizeof(buffer),&amp;byteread);   
        if(byteread==0)     
            break;   
        hwrite=WriteFile(createfile,buffer,sizeof(buffer),&amp;written,NULL);   
        if (hwrite==0)   
        {   
            cout&lt;&lt;"Write to file failed!"&lt;&lt;endl;   
            goto here;   
        }   
    }   
    cout&lt;&lt;"Finished downloading!"&lt;&lt;endl;   
here:   
    CloseHandle(createfile);   
next:    
    InternetCloseHandle(internetopenurl);   
there:   
    InternetCloseHandle(internetopen);   
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1133</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++获取电驴首页推荐 示例代码</title>
		<link>https://www.softwareace.cn/?p=1131</link>
		<comments>https://www.softwareace.cn/?p=1131#comments</comments>
		<pubDate>Thu, 29 Jan 2015 01:06:45 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1131</guid>
		<description><![CDATA[[crayon-69fb66a90a5b4908786436/]]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">/*******************************************************************************
*  @file        
*  @author      def&lt; qq group: 324164944 &gt;
*  @blog        http://www.cnblogs.com/itdef/
*  @brief     
/*******************************************************************************/
 
#include "stdafx.h"
 
#include &lt;afxinet.h&gt;
#include &lt;atlsimpstr.h&gt;
#include &lt;fstream&gt;  
#include &lt;iostream&gt;
#include &lt;sstream&gt;
 
#include &lt;set&gt;
 
using namespace std;
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
int GetHttpFileData(CString strUrl,char* DownloadHtmFileName);
int ParseHomePageDownloadFile(char* szfileName);
int UTF8Str2GBK(const string&amp; strUTF8,string&amp; strGBK);
void GetHomePageRecommend(char* szName,const string&amp; strGbk);
 
// 唯一的应用程序对象
 
CWinApp theApp;
 
using namespace std;
 
 
 
int ParseUpdateFile(char* szfileName)
{
    int iRet = -1;
 
    if(NULL == szfileName)
        return iRet;
 
    fstream fs(szfileName);
    stringstream ss ;   // 创建字符串流对象
    ss &lt;&lt; fs.rdbuf(); // 把文件流中的字符输入到字符串流中
    fs.close();
    string str = ss.str();  // 获取流中的字符串
    string strGbk;
 
    int i = UTF8Str2GBK(str,strGbk);
 
    if(strGbk.size() == 0 || i != 0)
    {
        cerr &lt;&lt; "transfer utf8 to gbk error" &lt;&lt; endl;
        return iRet;
    }
 
 
    basic_string &lt;char&gt;::size_type keyWordStart = strGbk.find("&lt;title&gt;");
    basic_string &lt;char&gt;::size_type keyWordEnd = strGbk.find("&lt;/title&gt;",keyWordStart+1);
 
    if( (keyWordStart != string::npos) &amp;&amp; (keyWordEnd != string::npos) &amp;&amp; (keyWordEnd &gt; keyWordStart) )
    {
        string strKeyWord = strGbk.substr(keyWordStart+7,keyWordEnd - keyWordStart -7);
        cout &lt;&lt; strKeyWord &lt;&lt; endl;
    }
 
 
 
    keyWordStart = strGbk.find("&lt;div class=\"cv-title\"&gt;");
    keyWordEnd = strGbk.find("&lt;/div&gt;",keyWordStart+1);
 
    if( (keyWordStart != string::npos) &amp;&amp; (keyWordEnd != string::npos) &amp;&amp; (keyWordEnd &gt; keyWordStart) )
    {
        string strKeyWord = strGbk.substr(keyWordStart+22,keyWordEnd - keyWordStart -22);
        cout &lt;&lt; strKeyWord &lt;&lt; endl;
    }
 
    iRet = 0;
    return iRet;
}
 
void ShowUpdateInfo(char* szHtmAddress)
{
    if ( 0 != GetHttpFileData(szHtmAddress,"HtmDownloadFile"))
    {
        cerr &lt;&lt; "GetHttpFileData error once" &lt;&lt; endl;   
    }
 
    if( 0 != ParseUpdateFile("HtmDownloadFile"))
    {
        cerr &lt;&lt; "ParseUpdateFile error once" &lt;&lt; endl;   
    }
 
 
}
 
 
void ShowHomePageElement(char* szHomePageAddress)
{
    if ( 0 != GetHttpFileData(szHomePageAddress,"HtmDownloadFile"))
    {
        cerr &lt;&lt; "GetHttpFileData error once" &lt;&lt; endl;   
    }
    if( 0 != ParseHomePageDownloadFile("HtmDownloadFile"))
    {
        cerr &lt;&lt; "GetHttpFileData error once" &lt;&lt; endl;   
    }
}
 
 
 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
 
    // 初始化 MFC 并在失败时显示错误
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: 更改错误代码以符合您的需要
        _tprintf(_T("错误: MFC 初始化失败\n"));
        nRetCode = 1;
    }
    else
    {
        // TODO: 在此处为应用程序的行为编写代码。
        ShowHomePageElement("http://www.verycd.com/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/790244/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/519062/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
         
        ShowUpdateInfo("http://www.verycd.com/entries/780306/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/522227/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/507338/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/515005/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/794197/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
 
        ShowUpdateInfo("http://www.verycd.com/entries/511135/");
        cout &lt;&lt; "****************************************************" &lt;&lt; endl;
         
    }
 
 
    system("pause");
         
    return nRetCode;
}
 
 
 
 
int UTF8Str2GBK(const string&amp; strUTF8,string&amp; strGBK)
{
    int i = MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, NULL, 0);
    WCHAR *wsz = NULL;
    TCHAR *tsz = NULL;
    int iRet = -1;
 
    wsz = new WCHAR[i+1];
    if( NULL == wsz)
    {
        goto UTF8Str2GBK_EXIT;
    }
    MultiByteToWideChar(CP_UTF8, 0, strUTF8.c_str(), -1, wsz, i);
 
    i = WideCharToMultiByte(CP_ACP, 0, wsz, -1, NULL, 0, NULL, NULL);
    tsz = new TCHAR[i+1];
    if( NULL == tsz)
    {
        goto UTF8Str2GBK_EXIT;
    }
    WideCharToMultiByte(CP_ACP, 0, wsz, -1, tsz, i, NULL, NULL);
     
    strGBK = string(tsz);
 
    iRet = 0;
UTF8Str2GBK_EXIT:
 
    delete []wsz;
    delete []tsz;
 
    return iRet;
}
 
 
int ParseHomePageDownloadFile(char* szfileName)
{
    int iRet = -1;
 
    if(NULL == szfileName)
        return iRet;
 
    fstream fs(szfileName);
    stringstream ss ;   // 创建字符串流对象
    ss &lt;&lt; fs.rdbuf(); // 把文件流中的字符输入到字符串流中
    fs.close();
    string str = ss.str();  // 获取流中的字符串
    string strGbk;
 
    int i = UTF8Str2GBK(str,strGbk);
 
    if(strGbk.size() == 0 || i != 0)
    {
        cerr &lt;&lt; "transfer utf8 to gbk error" &lt;&lt; endl;
        return iRet;
    }
    cout &lt;&lt; "首页大推" &lt;&lt; endl;
    GetHomePageRecommend("VeryCD.TrackEvent('base','首页大推',",strGbk);
    cout &lt;&lt; "首页小推" &lt;&lt; endl;
    GetHomePageRecommend("VeryCD.TrackEvent('base','首页小推',",strGbk);
 
 
    iRet = 0;
    return iRet;
}
 
 
void GetHomePageRecommend(char* szName,const string&amp; strGbk)
{
    set&lt;string&gt; setKeyWord;
    //cout &lt;&lt; strGbk;
    basic_string &lt;char&gt;::size_type keyWordStart = strGbk.find(szName);
    basic_string &lt;char&gt;::size_type keyWordEnd = strGbk.find("')",keyWordStart+1);
 
    if( (keyWordStart != string::npos) &amp;&amp; (keyWordEnd != string::npos) &amp;&amp; (keyWordEnd &gt; keyWordStart + 37) )
    {
        string strKeyWord = strGbk.substr(keyWordStart+37,keyWordEnd - keyWordStart - 37);
        setKeyWord.insert(strKeyWord);
 
        //cout &lt;&lt; "电驴首页小推  " &lt;&lt; strKeyWord &lt;&lt; endl;
    }
 
    while( keyWordStart != string::npos &amp;&amp; keyWordEnd != string::npos)
    {
        keyWordStart = strGbk.find(szName,keyWordEnd+1);
        keyWordEnd = strGbk.find("')",keyWordStart+1);
        if( (keyWordStart != string::npos) &amp;&amp; (keyWordEnd != string::npos) &amp;&amp; (keyWordEnd &gt; keyWordStart + 37) )
        {
            string strKeyWord = strGbk.substr(keyWordStart+37,keyWordEnd - keyWordStart - 37);
            setKeyWord.insert(strKeyWord);
            //cout &lt;&lt; "电驴首页小推  " &lt;&lt; strKeyWord &lt;&lt; endl;
        }
 
    }
 
    set&lt;string&gt;::iterator pos;
    for(pos = setKeyWord.begin();pos != setKeyWord.end();++ pos)
    {
        cout &lt;&lt; "电驴首页推荐  " &lt;&lt; *pos &lt;&lt; endl;
    }
 
}
 
 
 
int GetHttpFileData(CString strUrl,char* szDownloadHtmFileName)
{
    CInternetSession Session("Internet Explorer", 0);
    CHttpFile *pHttpFile = NULL;
    CString strData;
    CString strClip;
    int iRet = -1;
 
    if(szDownloadHtmFileName == NULL)
    {   
        cerr &lt;&lt; "DownloadHtmFileName is NULL" &lt;&lt; endl;
        Session.Close();
        return iRet;
    }
 
    ofstream of(szDownloadHtmFileName);
    if (of.bad())
    {
        cerr &lt;&lt; "of create file error" &lt;&lt; endl;
        Session.Close();
        return iRet;
    }
 
    try
    {
        pHttpFile = (CHttpFile*)Session.OpenURL(strUrl);
        while ( pHttpFile-&gt;ReadString(strClip) )
        {
            of &lt;&lt; strClip;
        }
    }catch(CInternetException* pEx)
    {
        TCHAR pszError[64];
        pEx-&gt;GetErrorMessage(pszError, 64);
        cerr &lt;&lt; __FUNCTION__ &lt;&lt; pszError &lt;&lt; endl;
        goto GetHttpFileData_EXIT;
    }
 
    iRet = 0;
 
GetHttpFileData_EXIT:
    Session.Close();
    of.close();
 
    return iRet;
}</pre><p><img src="http://static.oschina.net/uploads/code/201411/07190119_kk0K.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1131</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>获取公网IP</title>
		<link>https://www.softwareace.cn/?p=1033</link>
		<comments>https://www.softwareace.cn/?p=1033#comments</comments>
		<pubDate>Tue, 04 Nov 2014 12:48:39 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=1033</guid>
		<description><![CDATA[[crayon-69fb66a90a90a770561314/] &#160;]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">#include&lt;wininet.h&gt;
#pragma comment(lib,"wininet.lib")
 
DWORD HttpGet(LPCTSTR, char *, int);
void GetPublicIp(char *pIP, int len)
{
    char szBuffer[1024];
    memset(szBuffer, 0, sizeof(char) * 1024);
    if (HttpGet(_TEXT("http://city.ip138.com/ip2city.asp"), szBuffer, 1024))
    {
        char* begin = strstr(szBuffer, "[");
        char* end = strstr(begin, "]");
        if (begin == NULL || end == NULL)
            return;
        int offset = end - begin - 1;
        begin[offset] = '\0';
        char *ip = begin;
         
        strncpy_s(pIP, len, ip, offset);      
    }
}
 
DWORD HttpGet(LPCTSTR lpszFullUrl, char *pBuffer, int iBufferSize)
{
    if (lpszFullUrl == NULL)
        return 0;
 
    HINTERNET hNet = ::InternetOpen(_TEXT("Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0"),
        PRE_CONFIG_INTERNET_ACCESS,
        NULL,
        INTERNET_INVALID_PORT_NUMBER,
        0);
    if (hNet == NULL)
    {
        return 0;
    }
 
    HINTERNET hUrlFile = ::InternetOpenUrl(hNet,
        lpszFullUrl,
        NULL,
        0,
        INTERNET_FLAG_RELOAD,
        0);
 
    if (!hUrlFile)
    {
        return 0;
    }
 
    ::memset(pBuffer, 0, iBufferSize);
    DWORD dwBytesRead = 0;
    char szTemp[1024] = { 0 };
    DWORD dwTotalReadBytes = 0;
    while (InternetReadFile(hUrlFile, szTemp, sizeof(szTemp) - 1, &amp;dwBytesRead))
    {
        if (0 == dwBytesRead)
            break;
        szTemp[dwBytesRead] = 0; 
 
        // 缓冲区大小不够时，停止向目的缓冲区复制数据，跳出
        if (dwTotalReadBytes + dwBytesRead &gt;= (UINT)iBufferSize)
        {
            pBuffer[iBufferSize - 1] = 0;
            break;
        }
 
        strcat_s(pBuffer, 1024, szTemp);
        ZeroMemory(szTemp, sizeof(szTemp));
 
        dwTotalReadBytes += dwBytesRead;
 
    }
 
    ::InternetCloseHandle(hUrlFile);
    ::InternetCloseHandle(hNet);
    return dwTotalReadBytes;
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=1033</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TCP协议三次握手过程分析</title>
		<link>https://www.softwareace.cn/?p=787</link>
		<comments>https://www.softwareace.cn/?p=787#comments</comments>
		<pubDate>Tue, 29 Apr 2014 05:41:00 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=787</guid>
		<description><![CDATA[TCP(Transmission Control Protocol)　传输控制协议 TCP是主机对主机层的传输 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>TCP(Transmission Control Protocol)　传输控制协议</p>
<p>TCP是主机对主机层的传输控制协议，提供可靠的连接服务，采用三次握手确认建立一个连接:</p>
<p>位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)</p>
<p>Sequence number(顺序号码) Acknowledge number(确认号码)</p>
<p>第一次握手：主机A发送位码为syn＝1,随机产生seq number=1234567的数据包到服务器，主机B由SYN=1知道，A要求建立联机；</p>
<p>第二次握手：主机B收到请求后要确认联机信息，向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包</p>
<p>第三次握手：主机A收到后检查ack number是否正确，即第一次发送的seq number+1,以及位码ack是否为1，若正确，主机A会再发送ack number=(主机B的seq+1),ack=1，主机B收到后确认seq值与ack=1则连接建立成功。</p>
<p>完成三次握手，主机A与主机B开始传送数据。</p>
<p><span style="color: #0000ff;"><br />
在TCP/IP协议中，TCP协议提供可靠的连接服务，采用三次握手建立一个连接。<br />
第一次握手：建立连接时，客户端发送syn包(syn=j)到服务器，并进入SYN_SEND状态，等待服务器确认；<br />
第二次握手：服务器收到syn包，必须确认客户的SYN（ack=j+1），同时自己也发送一个SYN包（syn=k），即SYN+ACK包，此时服务器进入SYN_RECV状态； 第三次握手：客户端收到服务器的SYN＋ACK包，向服务器发送确认包ACK(ack=k+1)，此包发送完毕，客户端和服务器进入ESTABLISHED状态，完成三次握手。 完成三次握手，客户端与服务器开始传送数据.</span></p>
<p>实例:</p>
<p>IP 192.168.1.116.3337 &gt; 192.168.1.123.7788: S 3626544836:3626544836<br />
IP 192.168.1.123.7788 &gt; 192.168.1.116.3337: S 1739326486:1739326486 ack 3626544837<br />
IP 192.168.1.116.3337 &gt; 192.168.1.123.7788: ack 1739326487,ack 1</p>
<p>第一次握手：192.168.1.116发送位码syn＝1,随机产生seq number=3626544836的数据包到192.168.1.123,192.168.1.123由SYN=1知道192.168.1.116要求建立联机;</p>
<p>第二次握手：192.168.1.123收到请求后要确认联机信息，向192.168.1.116发送ack number=3626544837,syn=1,ack=1,随机产生seq=1739326486的包;</p>
<p>第三次握手：192.168.1.116收到后检查ack number是否正确，即第一次发送的seq number+1,以及位码ack是否为1，若正确，192.168.1.116会再发送ack number=1739326487,ack=1，192.168.1.123收到后确认seq=seq+1,ack=1则连接建立成功。</p>
<p>&nbsp;</p>
<p>图解：<br />
一个三次握手的过程（图1，图2）<br />
<img alt="" src="http://images.cnblogs.com/cnblogs_com/rootq/410601/r_1.jpg" border="0" /></p>
<p>&nbsp;</p>
<p>（图1）<br />
<img alt="" src="http://images.cnblogs.com/cnblogs_com/rootq/410601/r_2.jpg" border="0" /><br />
（图2）<br />
&nbsp;</p>
<p>第一次握手的标志位（图3）<br />
我们可以看到标志位里面只有个同步位，也就是在做请求(SYN)<br />
<img alt="3" src="http://images.cnblogs.com/cnblogs_com/rootq/410601/r_3.jpg" /><br />
（图3）</p>
<p>第二次握手的标志位（图4）<br />
我们可以看到标志位里面有个确认位和同步位，也就是在做应答(SYN + ACK)<br />
<img alt="4" src="http://images.cnblogs.com/cnblogs_com/rootq/410601/r_4.jpg" /><br />
（图4）</p>
<p>第三次握手的标志位（图5）<br />
我们可以看到标志位里面只有个确认位，也就是再做再次确认(ACK)<br />
<img alt="5" src="http://images.cnblogs.com/cnblogs_com/rootq/410601/r_5.jpg" /></p>
<p>（图5）</p>
<p>一个完整的三次握手也就是 请求&#8212;应答&#8212;再次确认</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=787</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TCP和UDP之间的区别</title>
		<link>https://www.softwareace.cn/?p=786</link>
		<comments>https://www.softwareace.cn/?p=786#comments</comments>
		<pubDate>Tue, 29 Apr 2014 05:39:41 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=786</guid>
		<description><![CDATA[TCP和UDP区别 TCP UDP 是否连接 面向连接 面向非连接 传输可靠性 可靠的 不可靠的 应用场合 传 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>TCP和UDP区别</p>
<div>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="96">
<div></div>
<div></div>
</td>
<td valign="top" width="124">
<div>TCP</div>
</td>
<td valign="top" width="96">
<div>UDP</div>
</td>
</tr>
<tr>
<td valign="top" width="96">
<div>是否连接</div>
</td>
<td valign="top" width="124">
<div>面向连接</div>
</td>
<td valign="top" width="96">
<div>面向非连接</div>
</td>
</tr>
<tr>
<td valign="top" width="96">
<div>传输可靠性</div>
</td>
<td valign="top" width="124">
<div>可靠的</div>
</td>
<td valign="top" width="96">
<div>不可靠的</div>
</td>
</tr>
<tr>
<td valign="top" width="96">
<div>应用场合</div>
</td>
<td valign="top" width="124">
<div>传输大量的数据</div>
</td>
<td valign="top" width="96">
<div>少量数据</div>
</td>
</tr>
<tr>
<td valign="top" width="96">
<div>速度</div>
</td>
<td valign="top" width="124">
<div>慢</div>
</td>
<td valign="top" width="96">
<div>快</div>
</td>
</tr>
</tbody>
</table>
<div></div>
<div> OSI 和 TCP/IP 模型在传输层定义两种传输协议：TCP（或传输控制协议）和 UDP（或用户数据报协议）。</p>
<div>
<div>UDP<br />
UDP 与 TCP 的主要区别在于 UDP 不一定提供可靠的数据传输。事实上，该协议不能保证数据准确无误地到达目的地。UDP 在许多方面非常有效。当某个程序的目标是尽快地传输尽可能多的信息时（其中任意给定数据的重要性相对较低），可使用 UDP。ICQ 短消息使用 UDP 协议发送消息。<br />
许多程序将使用单独的TCP连接和单独的UDP连接。重要的状态信息随可靠的TCP连接发送，而主数据流通过UDP发送。</div>
<div>TCP<br />
TCP的目的是提供可靠的数据传输，并在相互进行通信的设备或服务之间保持一个虚拟连接。TCP在数据包接收无序、丢失或在交付期间被破坏时，负责数据恢复。它通过为其发送的每个数据包提供一个序号来完成此恢复。记住，较低的网络层会将每个数据包视为一个独立的单元，因此，数据包可以沿完全不同的路径发送，即使它们都是同一消息的组成部分。这种路由与网络层处理分段和重新组装数据包的方式非常相似，只是级别更高而已。<br />
为确保正确地接收数据，TCP要求在目标计算机成功收到数据时发回一个确认（即 ACK）。如果在某个时限内未收到相应的 ACK，将重新传送数据包。如果网络拥塞，这种重新传送将导致发送的数据包重复。但是，接收计算机可使用数据包的序号来确定它是否为重复数据包，并在必要时丢弃它。</div>
<div>TCP与UDP的选择</div>
<div>    如果比较UDP包和TCP包的结构，很明显UDP包不具备TCP包复杂的可靠性与控制机制。与TCP协议相同，UDP的源端口数和目的端口数也都支持一台主机上的多个应用。一个16位的UDP包包含了一个字节长的头部和数据的长度，校验码域使其可以进行整体校验。（许多应用只支持UDP，如：多媒体数据流，不产生任何额外的数据，即使知道有破坏的包也不进行重发。）<br />
很明显，当数据传输的性能必须让位于数据传输的完整性、可控制性和可靠性时，TCP协议是当然的选择。当强调传输性能而不是传输的完整性时，如：音频和多媒体应用，UDP是最好的选择。在数据传输时间很短，以至于此前的连接过程成为整个流量主体的情况下，UDP也是一个好的选择，如：DNS交换。把SNMP建立在UDP上的部分原因是设计者认为当发生网络阻塞时，UDP较低的开销使其有更好的机会去传送管理数据。TCP丰富的功能有时会导致不可预料的性能低下，但是我们相信在不远的将来，TCP可靠的点对点连接将会用于绝大多数的网络应用。</div>
<div></div>
<div><span style="color: #ff0000;">TCP协议和UDP协议特性区别总结：</span></div>
<div><span style="color: #ff0000;">     1. TCP协议在传送数据段的时候要给段标号；UDP协议不</span></div>
<div><span style="color: #ff0000;">     2. TCP协议可靠；UDP协议不可靠</span></div>
<div><span style="color: #ff0000;">     3. TCP协议是面向连接；UDP协议采用无连接</span></div>
<div><span style="color: #ff0000;">     4. TCP协议负载较高，采用虚电路；UDP采用无连接</span></div>
<div><span style="color: #ff0000;">     5. TCP协议的发送方要确认接收方是否收到数据段（3次握手协议）</span></div>
<div><span style="color: #ff0000;">     6. TCP协议采用窗口技术和流控制</span></div>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=786</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ IE代理 设置</title>
		<link>https://www.softwareace.cn/?p=653</link>
		<comments>https://www.softwareace.cn/?p=653#comments</comments>
		<pubDate>Mon, 02 Dec 2013 04:00:10 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=653</guid>
		<description><![CDATA[最近有很多朋友都在讨论如何改变IE的代理 服务器 设置, 刚好我最近做的一个东西里面用到了这样的功能. 拿出来 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>最近有很多朋友都在讨论如何改变<span style="font-family: 'Times New Roman';">IE</span><span style="font-family: 宋体;">的代理 服务器 设置</span><span style="font-family: 'Times New Roman';">, </span><span style="font-family: 宋体;">刚好我最近做的一个东西里面用到了这样的功能</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">拿出来和大家共享一下</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">用到的关键函数是</span><span style="font-family: 'Times New Roman';">wininet</span><span style="font-family: 宋体;">库里面的</span><span style="font-family: 'Times New Roman';">InternetSetOption. msdn</span><span style="font-family: 宋体;">里面有对它详细的介绍</span><span style="font-family: 'Times New Roman';">, </span><span style="font-family: 宋体;">可以自己去看看</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">当把参数</span><span style="font-family: 'Times New Roman';">dwOption</span><span style="font-family: 宋体;">设置为</span><span style="font-family: 'Times New Roman';">INTERNE</span><span style="font-family: 宋体;">最近有很多朋友都在讨论如何改变</span><span style="font-family: 'Times New Roman';">IE</span><span style="font-family: 宋体;">的代理服务器设置</span><span style="font-family: 'Times New Roman';">,   </span><span style="font-family: 宋体;">刚好我最近做的一个东西里面用到了这样的功能</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">拿出来和大家共享一下</span><span style="font-family: 'Times New Roman';">. </span></p>
<p>&nbsp;</p>
<p>用到的关键函数是<span style="font-family: 'Times New Roman';">wininet</span><span style="font-family: 宋体;">库里面的</span><span style="font-family: 'Times New Roman';">InternetSetOption. msdn</span><span style="font-family: 宋体;">里面有对它详细的介绍</span><span style="font-family: 'Times New Roman';">, </span><span style="font-family: 宋体;">可以自己去看看</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">当把参数</span><span style="font-family: 'Times New Roman';">dwOption</span><span style="font-family: 宋体;">设置为</span><span style="font-family: 'Times New Roman';">INTERNET_OPTION_SETTINGS_CHANGED</span><span style="font-family: 宋体;">的时候</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">他就会促使</span><span style="font-family: 'Times New Roman';">IE</span><span style="font-family: 宋体;">在下一次打开网页的时候重新到注册表里面去取代理的设置信息</span><span style="font-family: 'Times New Roman';">.  </span><span style="font-family: 宋体;">所以我们就可以先将注册表里面的代理信息更改掉</span><span style="font-family: 'Times New Roman';">, </span><span style="font-family: 宋体;">然后调用</span><span style="font-family: 'Times New Roman';">InternetSetOption</span><span style="font-family: 宋体;">函数</span><span style="font-family: 'Times New Roman';">, </span><span style="font-family: 宋体;">从而达到使自己想要的代理设置马上生效的目的</span><span style="font-family: 'Times New Roman';">. </span></p>
<p>下面的函数可以实现改变<span style="font-family: 'Times New Roman';">IE</span><span style="font-family: 宋体;">的</span><span style="font-family: 'Times New Roman';">http</span><span style="font-family: 宋体;">代理服务器设置的目的</span><span style="font-family: 'Times New Roman';">. </span><span style="font-family: 宋体;">里面加了少许的注释以帮助大家理解</span><span style="font-family: 'Times New Roman';">.</span></p><pre class="crayon-plain-tag">BOOL SetHttpProxy(CString ip, UINT port)
{
 CString l_just;
 l_just.Format("http=%s:%d", ip.LockBuffer(), port); 

 //下面的代码将注册表项HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyServer
 //的内容取出来
 HKEY hKeyIn = HKEY_CURRENT_USER, hKeyOut;
 if( ERROR_SUCCESS != RegOpenKeyEx(hKeyIn, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_CREATE_LINK | KEY_WRITE | KEY_READ | KEY_NOTIFY, &amp;hKeyOut))
 {
  return FALSE;
 } 

 ULONG regsize = 0;
 if(ERROR_SUCCESS != RegQueryValueEx(hKeyOut, "ProxyServer", NULL, NULL, NULL, &amp;regsize))
 {
  return FALSE;
 }

 LPBYTE pValue = new BYTE[regsize];
 memset(pValue, 0x00, regsize); 

 if(ERROR_SUCCESS != RegQueryValueEx(hKeyOut, "ProxyServer", NULL, NULL, pValue, &amp;regsize))
 {
  return FALSE;
 } 

 CString oldproxy((char *)pValue);
 delete [] pValue;
 pValue = NULL; 

 //从注册表中读出来的数据格式为:http=111.111.111.111:80;ftp=222.222.222.222:21;......, 
 //如果你只想改变http的代理的话， 就只要把其中的111.111.111.111:80换成你想要的代理就行了，
 //类似的你可以改变其他的代理. 

 //下面的代码就替换http代理成为参数所指定的代理.
 int pos = 0;
 //如果没有字符串中没有找到"http="说明用户没有设置http代理，这时候直接加在最前面.
 if(-1 == (pos = oldproxy.Find("http=")))
 {
  pos = 0;
 } 
 int pos1 = 0;
 if(-1 == (pos1 = oldproxy.Find(";", pos)))
 {
  pos1 = oldproxy.GetLength();
 } 
 oldproxy.Delete(pos, pos1 - pos);
 oldproxy.Insert(pos, l_just); 

 if(ERROR_SUCCESS != RegSetValueEx(hKeyOut, "ProxyServer", 0, REG_SZ, (const unsigned char *)oldproxy.LockBuffer(), oldproxy.GetLength() + 1))
 {
  return FALSE;
 } 
 RegCloseKey(hKeyOut); 
 //使设置生效
 if(!InternetSetOption(NULL, INTERNET_OPTION_SETTINGS_CHANGED, NULL, 0))
 {
  return FALSE;
 } 
 return TRUE;
}</pre><p>最后在使用此函数的时候不要忘记包含头文件 <span style="font-family: 'Times New Roman';">#include &lt;wininet.h&gt; </span><span style="font-family: 宋体;">和</span><span style="font-family: 'Times New Roman';">lib: wininet.lib </span></p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=653</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vc下载类</title>
		<link>https://www.softwareace.cn/?p=629</link>
		<comments>https://www.softwareace.cn/?p=629#comments</comments>
		<pubDate>Thu, 17 Oct 2013 06:17:16 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[net work]]></category>

		<guid isPermaLink="false">http://www.softwareace.cn/?p=629</guid>
		<description><![CDATA[[crayon-69fb66a90af48738104079/] &#160; [crayon-69fb66a [&#8230;]]]></description>
				<content:encoded><![CDATA[<p></p><pre class="crayon-plain-tag">// NetGrab.h: interface for the URLDownloadFile class.
#include &lt;afxinet.h&gt;
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_URLDOWNLOADFILE_H__D2012F54_4448_4679_909D_95BB6646862C__INCLUDED_)
#define AFX_URLDOWNLOADFILE_H__D2012F54_4448_4679_909D_95BB6646862C__INCLUDED_

#if _MSC_VER &gt; 1000
#pragma once
#endif // _MSC_VER &gt; 1000

class NetGrab
{
public:
	//设置显示速率的控件句柄
	BOOL SetRateWnd(CWnd* pWnd);
	//设置进度条对象
	BOOL SetProcessBar(CProgressCtrl* pProcessBar);
	//取得文件大小
	DWORD GetFileSize();
	//取得缓冲区大小
	DWORD GetBufSize();
	//设置缓冲区大小
	BOOL SetBufSize(DWORD dSize);
	//下载文件到缓冲区
	CString URLGetFileToBuf(CString sURL);
	//下载文件到本地
	BOOL URLDownloadToFile();
	//下载文件到本地(两个参数)
	BOOL URLDownloadToFile(CString sURL,CString sSavePath);
	//下载文件到本地(四个参数)
	BOOL URLDownloadToFile(CString sURL,CString sSavePath, CProgressCtrl* pProcessBar,CWnd* pWnd);
	//远程URL
	CString sURL;
	//本地文件
	CString sSavePath;
	NetGrab();
	virtual ~NetGrab();
private:
	BOOL RepairURL(CString sURL);
	BOOL GetTransferRateWinText(COleDateTime startTime,double dCurrentbytes);
	//缓冲区大小
	DWORD BUFFER_SIZE;
	//文件大小
	DWORD dFileSize;
	//进度条对象指针
	CProgressCtrl* m_pProcessBar;
	//显示下载速度的控件句柄
	CWnd* m_pRateWnd;
	//速率
	CString	sTransferRate;
	CInternetSession *m_pInetSession;
	CHttpConnection *m_pCHttpConn;

};

#endif // !defined(AFX_URLDOWNLOADFILE_H__D2012F54_4448_4679_909D_95BB6646862C__INCLUDED_)</pre><p>&nbsp;</p><pre class="crayon-plain-tag">// NetGrab.cpp: implementation of the URLDownloadFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NetGrab.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

NetGrab::NetGrab()
{
	m_pInetSession = NULL;
	CStdioFile *pSFile = NULL;
	try
	{
		//创建 CInternetSession对象,初始化WinInet,并连接服务器
		m_pInetSession=new CInternetSession(NULL,
			1,
			INTERNET_OPEN_TYPE_DIRECT,
			NULL,
			NULL,
			INTERNET_FLAG_DONT_CACHE);

		//设置参数
		m_pInetSession-&gt;SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,10000,1);
		m_pInetSession-&gt;SetOption(INTERNET_OPTION_CONNECT_BACKOFF,10000);
		m_pInetSession-&gt;SetOption(INTERNET_OPTION_CONNECT_RETRIES,1);
	}
	catch (CInternetException* lpEx)
	{
		lpEx-&gt;Delete();
	}
	//默认缓冲区大小
	BUFFER_SIZE = 10*1024;
	dFileSize = 0;
	//进度条
	m_pProcessBar = NULL;
	m_pRateWnd = NULL;
}

NetGrab::~NetGrab()
{
	if (m_pInetSession)
    {
        m_pInetSession-&gt;Close();
        delete m_pInetSession;
    }
    m_pInetSession = NULL;
	m_pProcessBar = NULL;
	m_pRateWnd = NULL;
}

BOOL NetGrab::URLDownloadToFile(CString sURL, CString sSavePath,CProgressCtrl* pProcessBar,CWnd* pWnd)
{
	this-&gt;sURL = sURL;
	this-&gt;sSavePath = sSavePath;
	m_pProcessBar = pProcessBar;
	m_pRateWnd = pWnd;
	if (!URLDownloadToFile())
	{
		return FALSE;
	}
	return TRUE;
}

CString NetGrab::URLGetFileToBuf(CString sURL)
{
	CString sBuf;
	sBuf.Empty();
	CStdioFile *pNetFile = NULL;
	try
	{
		pNetFile = m_pInetSession-&gt;OpenURL(sURL.GetBuffer(sURL.GetLength()));
	}
	catch (CInternetException* lpEx)
	{
		lpEx-&gt;Delete();
		pNetFile = NULL;
		return sBuf;
	}
	try
	{
		//从缓冲区循环读取数据
		CString tmpBuf;
		while (pNetFile-&gt;ReadString(tmpBuf))
		{
			sBuf += tmpBuf;
			tmpBuf.Empty();
		}
		//更准确得到文件实际大小(字节)
		dFileSize = strlen(sBuf);
	}
	catch (CFileException* lpEx)
	{
		lpEx-&gt;Delete();
		sBuf.Empty();
		dFileSize = 0;
		return sBuf;
	}

	return sBuf;
}

BOOL NetGrab::SetBufSize(DWORD dSize)
{
	BUFFER_SIZE = dSize;
	return TRUE;
}

DWORD NetGrab::GetBufSize()
{
	return BUFFER_SIZE;
}

DWORD NetGrab::GetFileSize()
{
	return dFileSize;
}

BOOL NetGrab::GetTransferRateWinText(COleDateTime startTime, double dCurrentbytes)
{
	if (NULL!=m_pRateWnd)
	{
		COleDateTimeSpan elapsed = COleDateTime::GetCurrentTime() - startTime;
		//时间差转换为秒
		double dSecs = elapsed.GetTotalSeconds();
		sTransferRate.Format("%0.1f KB/s",(double)dCurrentbytes/1024.0/dSecs);
		sTransferRate.Replace("$","0");
		m_pRateWnd-&gt;SetWindowText(sTransferRate);
	}

	return TRUE;
}

BOOL NetGrab::SetProcessBar(CProgressCtrl *pProcessBar)
{
	m_pProcessBar = pProcessBar;
	return TRUE;
}

BOOL NetGrab::SetRateWnd(CWnd *pWnd)
{
	m_pRateWnd = pWnd;

	return TRUE;
}

BOOL NetGrab::URLDownloadToFile()
{
	if (!RepairURL(sURL))
	{
		return FALSE;
	}
	CStdioFile *pNetFile = NULL;
	try
	{
		pNetFile = m_pInetSession-&gt;OpenURL(sURL.GetBuffer(sURL.GetLength()));
		if (pNetFile==NULL)
		{
			return FALSE;
		}

		if (NULL!=m_pProcessBar)
		{
			//得到文件大小,必须站点支持
			dFileSize = pNetFile-&gt;SeekToEnd();
			pNetFile-&gt;SeekToBegin();
			//设置进度条宽度
			m_pProcessBar-&gt;SetRange32(0,dFileSize);
		}
	}
	catch (CInternetException* lpEx)
	{
		lpEx-&gt;Delete();
		pNetFile = NULL;
		return FALSE;
	}
	CFile pLocalFile = NULL;
	try
	{
		pLocalFile.Open(sSavePath.GetBuffer(sSavePath.GetLength()),
			CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
		BYTE *pBuf = new BYTE[BUFFER_SIZE];
		int Currentbytes = 0;
		//当前时间
		COleDateTime startTime = COleDateTime::GetCurrentTime();
		//从缓冲区循环读取数据
		while (int bytesread = pNetFile-&gt;Read(pBuf,BUFFER_SIZE))
		{
			//当前已读取字节数
			Currentbytes += bytesread;
			//取得下载速度
			GetTransferRateWinText(startTime,Currentbytes);
			//指针移到文件结尾
			pLocalFile.SeekToEnd();
			//将读取的缓冲区数据写入本地文
			pLocalFile.Write(pBuf,bytesread);
			if (NULL!=m_pProcessBar)
			{
				m_pProcessBar-&gt;SetPos(Currentbytes);
			}
		}
		//更准确得到文件实际大小
		dFileSize = Currentbytes;
		delete[] pBuf;
	}
	catch (CFileException* lpEx)
	{
		lpEx-&gt;Delete();
		dFileSize = 0;
		return FALSE;
	}
	//关闭本地文件
	if (NULL!=pLocalFile)
	{
		pLocalFile.Close();
	}
	//关闭CStdioFile
	if (NULL!=pNetFile)
	{
		pNetFile-&gt;Close();
	}

	return TRUE;
}

BOOL NetGrab::URLDownloadToFile(CString sURL, CString sSavePath)
{
	this-&gt;sURL = sURL;
	this-&gt;sSavePath = sSavePath;
	if (!URLDownloadToFile())
	{
		return FALSE;
	}
	return TRUE;
}

BOOL NetGrab::RepairURL(CString sURL)
{
	sURL.TrimLeft();
	sURL.TrimRight();
	sURL.Replace('\\','/');
	if (sURL.IsEmpty())
	{
		return FALSE;
	}
	int iPos = sURL.Find("://",0);
	CString sURLHead = sURL.Left(iPos);
	sURLHead.MakeLower();
	if (sURLHead!="http" &amp;&amp; sURLHead!="ftp" &amp;&amp; sURLHead!="https")
	{
		sURL = "http://" + sURL;
	}
	this-&gt;sURL = sURL;
	return TRUE;
}</pre><p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://www.softwareace.cn/?feed=rss2&#038;p=629</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
