﻿<?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>C++博客-阿π-随笔分类-网络编程</title><link>http://www.cppblog.com/lapcca/category/12921.html</link><description>专注于网络协议,系统底层,服务器软件</description><language>zh-cn</language><lastBuildDate>Thu, 18 Nov 2010 03:53:25 GMT</lastBuildDate><pubDate>Thu, 18 Nov 2010 03:53:25 GMT</pubDate><ttl>60</ttl><item><title>设计winsock服务器需要注意的几个问题</title><link>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 12 Nov 2010 06:04:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/133421.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/133421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/133421.html</trackback:ping><description><![CDATA[<p>6.2.1 接受连接的方法 </p>
		<p>Winsock 扩展函数 AcceptEx 是唯一能够使用重叠 I/O 接受客户连接的函数。下面主要深入探讨使用该函数接收连接的问题。 </p>
		<p>前面已经讨论过，当客户连接进来时，服务器需要创建一个套接字来负责维护与一个客户端的会话。使用 AcceptEx 函数之前必须创建一些套接字，并且这些套接字必须是未绑定、未连接的，即使它们可能在调用 TransmitFile, TransmitPackets, 或 DisconnectEx 后可以重用。 </p>
		<p>响应服务器必须总是具有足够的 AcceptEx 在站岗，以便在有客户连接请求时调用。但是，并没有具体的数量能够保证服务器能够立即响应连接。我们知道在调用 listen 将监听套接字置于监听状态后， TCP/IP 堆栈会自动接受到来的连接，直到达到 listen 的 backlog 参数设定的限制。对于 Windows NT 服务器而言，支持的 backlog 的最大值为 200 。如果服务器投递了 15 个 AcceptEx 调用，然后突然有 50 个客户请求连接服务器，它们的连接请求都不会遭到拒绝。服务器投递的 AcceptEx I/O 会满足前面的 15 个连接，剩下的 35 个连接都被系统默认连接了。检查一下 backlog 的值发现，系统还有能力默认接受 165 个连接。之后，如果服务器投递 AcceptEx 调用，它们会立即成功返回，因为系统会将默认接收的连接放入 “ 等待连接队列 ” 中。 </p>
		<p>服务器的特性是决定要投递多少个 AcceptEx 操作的重要因素。例如，希望处理大量短时间即时连接的客户要比处理少量长时间连接的客户投递更多的 AcceptEx I/O 。一个好的策略是允许 AcceptEx 的调用数量在最小值和最大值之间变化。具体做法是，应用程序跟踪未决的 AcceptEx I/O 的数量，当一个或多个 I/O 完成使这个未决 I/O 数量变得比最小值还小时，就再投递额外的 AcceptEx I/O 。 </p>
		<p>在 Windows 2000 和以后的 Windows 操作系统版本中， Winsock 提供了一种机制，用来确定应用程序是否投递了足够的 AcceptEx 调用。创建监听套接字时，使用 WSAEventSelect 函数为监听套接字关联一个事件对象，注册 FD_ACCEPT 事件。如果投递的 AcceptEx 操作用完，但是仍有客户请求接入（系统根据 backlog 值决定是否接受这些连接），事件对象就是受信，说明应该投递额外的 AcceptEx 操作了。这实际上还是利用事件对象来使调用线程处于一种 “ 可警告状态 ” ，当有客户连接请求时，就根据当前 AcceptEx 操作是否用完来警告（通知）是否需要投递新的 AcceptEx 操作来处理新的客户连接。 </p>
		<p>使用 AcceptEx 处理连接的另外一个功能就是在处理连接时还可以接收用户发来的第一块数据（前提是为 AcceptEx 提供了接收缓冲区），这对于那些请求连接的同时发送了一些数据过来的客户来说很适用。但是，此时，除非接收连接的同时接收到了客户发送过来的一些数据，否则 AcceptEx 是不会返回的。 </p>
		<p>为了满足客户的需求，服务器不得不投递更多的接受 I/O ，这会占用大量的系统资源。如果客户仅调用 connect 函数连接服务器，长时间既不发送数据，也不关闭连接，就可能造成 AcceptEx 投递的大量重叠 I/O 操作不能返回。这就是 “ 恶意连接 ” 。为此，服务器应该记录每个 AcceptEx 投递的未决 I/O, 定时扫描它们，设置 SO_CONNECT_TIME 参数调用 getsockopt 检查它们连接的时间，如果超时，就将连接关闭。如果使用 WSAEventSelect 模型来通知有连接事件，则当事件受信时，是检查客户套接字（ AcceptSocket ）是否真正连接了。 </p>
		<p>每当调用 AcceptEx 接受客户端连接时，它也在等待接受客户发送过来的第一个数据块，这时不允许投递另外一个 AcceptEx 。当 AcceptEx 返回后，如果事件对象再次受信则表明有新的连接到来。需要注意的是，无论何时，千万不要关闭一个调用 AcceptEx 还没有返回的套接字（ AcceptSocket ），因为这会导致内存泄露。因为从内部执行逻辑看，当没有连接的套接字句柄被关闭时，调用 AcceptEx 所涉及到的内核模式的数据结构并不会清除掉，直到有新的连接建立或者监听套接字被关闭。 </p>
		<p>尽管在一个等待完成通知的工作者线程中，投递一个 AcceptEx 操作，看起来既简单又合情合理，但是应尽量避免这样做，因为创建套接字还是很耗费资源的。另外，也不要在工作者线程中进行任何复杂的计算，以便处理器可以尽快的在接到完成通知后进行后续处理。创建套接字耗费资源的一个原因在于 Winsock 2.0 本身的架构很复杂，成功地创建一个套接字可能需要调用很多内核服务。因此，服务器应该在单独线程中创建套接字，投递 AcceptEx 操作。当调用线程投递的 AcceptEx 重叠操作完成时，一个受信的事件将会通知处理线程。 </p>
		<p>6.2.2 数据传输问题 </p>
		<p>数据传输是通信程序执行的核心操作。当一个客户与服务器建立连接后，它们的主要工作就是传输数据，因为数据是信息的表示。由上一节几种 I/O 模型的性能测试分析可知，当连接数量很大时，数据吞吐量是一个重要的性能考核指标。 </p>
		<p>从性能角度考虑，所有的数据传输最好都应采用重叠 I/O 处理。默认情况下，系统为每个 socket 分配一个的接受缓冲区和一个发送缓冲区，用来缓存接收和发送的数据。但在重叠 I/O 中，这些缓冲区往往不用，可以传递参数 SO_SNDBUF 或 SO_RCVBUF 调用 setsockopt ，来将它们设置为 0 。 </p>
		<p>让我们来看看，当发送缓冲区没有设置为 0 时，系统是怎么处理一个典型的 send 操作的。当一个应用程序调用 send 函数时，如果有充足的缓冲空间，需要发送的数据将被拷贝到套接字的发送缓冲区， send 函数立即成功返回，并且一个完成通知被抛出。另外一个方面，如果套接字的发送缓冲区已满，则应用程序提供的发送缓冲区被锁定，再次对 send 函数的调用将会返回 WSA_IO_PENDING 错误。当发送缓冲区中的数据被处理（例如，提交给传输层处理）时， Winsock 实际上直接处理锁定在缓冲区中的数据，也即绕过套接字的发送缓冲区，直接从应用程序缓冲区中提交数据给传输层。 </p>
		<p>接收数据的情况恰好相反。当一个重叠的 receive 请求抛出后，如果数据已经接收成功，它会被缓存在套接字接收缓冲区。数据会拷贝到应用程序缓冲区（直到饱和）。 receive 调用返回，并且一个完成通知被抛出。当套接字缓冲区被设置为空时，如果调用重叠的 receive 操作将返回 WSA_IO_PENDING 错误。当有数据到达时，它将绕过套接字缓冲区而直接被拷贝到应用程序缓冲区。 </p>
		<p>设置单套接字缓冲区为 0 ，并不能提高性能，因为只要一直有大量的重叠接发请求被抛出，就不会有额外的内存拷贝。设置套接字发送缓冲区为空比设置套接字接收缓冲区为空对系统的性能影响要小。因为应用程序的发送缓冲区会被经常锁定直到它被提交给传输层处理。然而，若将接收缓冲区设置为 0 ，并且没有重叠的 receive 调用，任何传进来的数据只能缓存在传输层。传输层驱动程序只会缓存滑动窗口尺寸的数据，即 17KB— 传输层可以分配的缓冲区大小的上限。实际的缓冲区要比 17KB 小。传输层缓冲区（针对一次连接）是在非分页池之外分配的，这意味着，当服务建立了 1000 个连接时，即使没有抛出 receive 请求，非分页池中也会分配 17MB 的内存。而非分页池是很珍贵的资源，除非服务器可以保证总是有接收请求抛出，否则套接字接收缓冲区应该不需设置。 </p>
		<p>只有在一些特殊情况下，对套接字接收缓冲区不予设置将会导致性能降低。考虑服务器需要处理成千上万个客户连接，而每个连接上又都没有投递 receive 请求的情况，如果客户端零星地发送数据过来，传输进来的数据将被缓存在套接字接收缓冲区中。当服务器处理一个 receive 重叠 I/O 时，它会做一些不必要的工作。当完成通知到达时，重叠操作会处理一个 I/O 请求包（ IRP ）。在这种情形下，服务器不能保留很多抛出的 receive 请求。因此，最好使用简单的非阻塞接收函数。 </p>
		<p>6.3 内存资源管理问题 </p>
		<p>由于机器硬件条件所限，系统资源是有限的，因此不得不考虑内存资源的管理问题。从上一节对不同 I/O 模型进行的性能测试结果分析可知，维持大规模的通信连接，不仅会耗费掉大量内存，而且对 CPU 的占用也是很高的。 </p>
		<p>对于配置比较高的服务器而言，处理成千上万个连接并不成问题。但是随着连接量的剧增，内存资源的限制将逐渐凸现。最有可能遇到的两个限制因素就是锁定页和非分页池。锁定页的限制不是太严重，更应该避免的是非分页池被耗尽。每一次调用重叠的 send 或 receive 请求，提交的缓冲区都可能被锁住。当内存被锁定时，它就不能从物理内存换出。操作系统对锁定内存的数量是有限制的，当达到极限时，重叠操作将会返回 WSAENOBUFS 错误。如果服务器在每个连接上投递多个重叠接收操作，随着客户连接数量的增多，极限就会达到。如果期望服务器能够处理高并发通信，服务器可以在每个连接上投递一个 0 字节的接受操作，这样就不会有内存锁定。 0 字节的接受完成以后，服务器可以简单地执行一个非阻塞的接收函数来获取缓存在套接字接收缓冲区中的所有数据。当非阻塞接收调用返回 WSAEWOULDBLOCK 时，就表示不再有未决的数据了。这种方法非常适合用来设计那些希望通过牺牲每个套接字上的吞吐率来获取更大规模并发连接的服务器。 </p>
		<p>当然，最好还要了解客户端与服务器通信的方式。在上面的例子中，当 0 字节的接收完成后，再投递一个异步接收操作，将接收到所有缓存在套接字接收缓冲区中的数据。如果服务器知道客户端将会连续不断发送数据，那么当 0 字节的接收完成后，假如客户端将发送大数据块（超过单套接字缓冲区 8KB 的容量）过来，服务器将抛出一个或多个重叠的接收操作。 </p>
		<p>另外一个需要重点考虑的问题就是系统所需页的数量。当系统锁定传递给重叠操作的内存时，它是在页边界上进行的。在 x86 体系结构上，内存页的大小为 4KB 。如果一个操作投递了 1KB 的缓冲区，系统实际上会为它锁定 4KB 大小的内存块。为避免这种浪费，重叠发送和接收缓冲区的大小应该是页大小的倍数。可以使用 GetSystemInfo 这个 API 来获知当前系统页的大小。 </p>
		<p>如果突破非分页池极限，将会导致更严重的错误，并且很难恢复。非分页池是内存的一部分，它常驻内存，并且永远不会被交换出去。内核模式的系统组件，如驱动程序，通常使用非分页池，其中包括 Winsock 和协议驱动程序，例如 tcpip.sys 。每个套接字的创建将消耗一小部分非分页池，用于维持套接字状态信息。当套接字绑定到一个地址后， TCP/IP 堆栈将分配额外的非分页池来保存本地地址的信息。当一个对等套接字接入后， TCP/IP 堆栈也将分配部分非分页池来保存远程地址信息。基本上，一个建立连接的套接字占用 2KB 非分页池内存 , 而 accept 或 AcceptEx 返回的套接字则占用 1.5KB 非分页池内存。之所以出现这个区别，是因为服务器本地地址信息已经存储在监听套接字中，故 accept 或 AcceptEx 返回的套接字只需保存远程主机地址信息。此外，每个在套接字上投递的重叠操作都需要给 I/O 请求包（ IRP ）分配内存，一个 IRP 使用大约 500B 非分页池内存。 </p>
		<p>从以上分析可以看出，为每个连接分配的非分页池内存并不是很大。然而，随着客户连接量逐增，服务器对非分页池的使用将是非常大的。考虑运行在只有 1GB 物理内存的 Windows 2000 或以后版本 Windows 系统上的服务器，将有 256MB 的内存非配给非分页池。通常，非分页池大小是机器物理内存的 1/4 ， Windows 2000 及以后版本的 Windows 系统上，非分页池大小为 256MB （ /1GB ），而 Windows NT 4.0 限制为 128MB （ 1GB ）。拥有 256MB 的非分页池的服务器可以支持 50,000 或更大的连接量。但是必须限制重叠的 accept 数量，以及在已经建立连接的重叠收发操作。在这个例子中，如果已经建立连接的套接字，按每个 1.5KB 计算，将耗费 75MB 的非分页池内存。如果采用了上面提及的投递 0 字节接收的方法，这样为每个连接分配的 IRP 将占用 25MB 的非分页池内存。 </p>
		<p>如果系统耗尽了非分页池，会有两种可能的后果。在最好的情况下， Winsock 调用将返回 WSAENOBUFS 错误。最糟糕的情况是系统崩溃，这种情况通常是系统没能正确处理内存非配的问题造成的。没有一种可行的方案能够恢复非分页池耗尽的错误，并且也没有可行的方案来监视非分页池可分配的大小，因为非分页池耗尽导致系统崩溃。 </p>
		<p>由以上探讨，可以得出结论，没有一种方法可以确定服务器到底支持多大的并发连接和重叠操作，并且也不可能准确地获知非分页池是否耗尽或者锁定内存页数超过极限。因为它们都将导致 Winsock 调用都返回相同的错误 —WSAENOBUFS 。因为以上因素，针对服务器的测试必须测试不同数量的连接情况以及重叠操作完成情况，以便在并发通信规模和数据吞吐率这两个指标之间选择一种折中的方案。如果在方案中强加限制，以防止服务器耗尽非分页池，则返回 WSAENOBUFS 错误时，我们就知道是因为超过了锁定页的限制。并且可以以一种更优化的处理方式编写程序，如进一步限制一些待决的操作或关闭某些连接。 </p>
		<p>包重新排序问题 </p>
		<p>这个问题与伸缩性没有多大关联，但是却是实际通信中不得不考虑的一个问题，因为它涉及到能否正确通信的问题。 </p>
		<p>虽然使用完成端口的 I/O 操作总是会按照它们被提交的顺序完成，但是线程调度问题可能会导致关联到完成端口上的工作不能按正常顺序完成。例如，有两个 I/O 工作线程，应该接收 “ 字节块 1 ，字节块 2 ，字节块 3” ，但是你可能以错误顺序接收这 3 个字节块： “ 字节块 2 ，字节块 1 ，字节块 3” 。这也意味着在完成端口上投递发送请求发送数据时，数据实际也会以错误顺序被发送出去。 </p>
		<p>当然，如果只使用一个工作线程，仅提交一个 I/O 调用，是不存在顺序问题的。因为同一时刻，一个工作线程只能处理一个 I/O 操作。但是，这样就没有发挥出完成端口的真正优点。 </p>
		<p>如第 3 章《自定义应用层通信协议》所述，一个简单的解决方法就是为每个封包添加一个协议头。协议头主要是一个封包的实际字节数，如自定义 Package 包的第一个字段 m_nCmdLen 就是这个包占用的字节数。通信的接受方通过分析协议头分析本次通信有多少数据要接收，然后继续读后面的数据，直到一个封包被完整接收完才接收下一个封包。 </p>
		<p>当服务器一次仅做一个异步调用时，上述封包协议头的解决方案是很有效的。但是，如果要充分发挥 IOCP 服务器的潜力，肯定有多个未决的异步读操作等待数据的到来。这意味着，多个一步操作不能按顺序完成，未决读 I/O 返回的字节流不能按顺序处理，接收到的字节流可能组合成正确的封包，也有可能组合成错误的封包。因此，要解决这个问题，还必须为提交的读 I/O 分配序列号。 </p>
		<p>  </p>
		<p>说明： </p>
		<p>本文主要译自《 Network programming for microsoft windows 》一书的 6.2 节《可伸缩的服务器体系结构》和 6.3 节《资源管理》。 </p>
		<p>其中包重新排序问题，参考 王艳平著 《 Windows 网络与通信程序设计 》 4.3.4 节《包重新排序问题》 。 </p><img src ="http://www.cppblog.com/lapcca/aggbug/133421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-12 14:04 <a href="http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[收藏学习]QQ农场外挂源码文章</title><link>http://www.cppblog.com/lapcca/archive/2010/11/10/133177.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Wed, 10 Nov 2010 01:45:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/10/133177.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/133177.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/10/133177.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/133177.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/133177.html</trackback:ping><description><![CDATA[<p>这东西是以前觉得QQ农场比较有意思的时候写的,后来还让我同学帮忙分析分析数据, </p>
		<p>结果后来太忙了,就一直荒废着,一直荒废到现在连QQ农场都快遗忘了 , </p>
		<p>现在将我的分析与源代码 (VC++ 6.0) 发出来,有兴趣可以拿去研究研究 </p>
		<p>分析文件里面有关键 swf 的编译文件 </p>
		<p>QQ农场的外挂并不难,主要是要分析的数据比较多,比较难解决的是 farmKey 的生成,最早的 farmKey 是直接在 </p>
		<p>farmTime 后面加个字符然后MD5得到,后来又好像改算法了,刚才又搜索了一下,貌似现在是不验证farmKey了, <br />如果真的是不验证了,那就比较好办 </p>
		<p>我当时有个比较好的想法是, 当你要执行你自己的操作时,比如要偷菜,先点击自己的农场, </p>
		<p>这时候会发送一个请求信息到服务器 </p>
		<p>发送:70 send: (sock=1888, ,len=70,flags=0) <br />farmKey=94650692c95593003ca5a334e349020e&amp;ownerId=0&amp;farmTime=1250599404 </p>
		<p>这时候,你可以截取这个数据,保存 farmkey,然后在后面修改你要的操作, </p>
		<p>这样,无论他算法怎么换,你在这里截取farmKey 就行. 当然如果你能破解farmKey生成当然是最好的 </p>
		<p>希望对研究这个游戏外挂有所帮助, !!!!!!!!!! <br /><br /><br /><a href="/Files/lapcca/QQ农场外挂源码和分析资料源代码.zip">见源码</a></p><img src ="http://www.cppblog.com/lapcca/aggbug/133177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-10 09:45 <a href="http://www.cppblog.com/lapcca/archive/2010/11/10/133177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络通讯协议图</title><link>http://www.cppblog.com/lapcca/archive/2010/11/04/132434.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Thu, 04 Nov 2010 06:13:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/04/132434.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/132434.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/04/132434.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/132434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/132434.html</trackback:ping><description><![CDATA[<img src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_wlxyt.jpg" />
		<a href="/Files/lapcca/网络通讯协议图.zip">
				<br />
				<br />
				<br />
				<br />
				<br />下载pdf版</a><img src ="http://www.cppblog.com/lapcca/aggbug/132434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-04 14:13 <a href="http://www.cppblog.com/lapcca/archive/2010/11/04/132434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分享以前收藏的TCP状态转换图</title><link>http://www.cppblog.com/lapcca/archive/2010/11/02/132139.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Tue, 02 Nov 2010 06:41:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/02/132139.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/132139.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/02/132139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/132139.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/132139.html</trackback:ping><description><![CDATA[<img src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_tcp%e7%8a%b6%e6%80%81%e8%bd%ac%e6%8d%a2%e5%9b%be.jpg" /><img src ="http://www.cppblog.com/lapcca/aggbug/132139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-02 14:41 <a href="http://www.cppblog.com/lapcca/archive/2010/11/02/132139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Socket粘包问题</title><link>http://www.cppblog.com/lapcca/archive/2010/09/10/126329.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 10 Sep 2010 09:49:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/09/10/126329.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/126329.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/09/10/126329.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/126329.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/126329.html</trackback:ping><description><![CDATA[<p>这两天看csdn有一些关于socket粘包，socket缓冲区设置的问题，发现自己不是很清楚，所以查资料了解记录一下：</p>
		<p>一两个简单概念长连接与短连接：<br />1.长连接</p>
		<p>    Client方与Server方先建立通讯连接，连接建立后不断开， 然后再进行报文发送和接收。</p>
		<p>2.短连接</p>
		<p>    Client方与Server每进行一次报文收发交易时才进行通讯连接，交易完毕后立即断开连接。此种方式常用于一点对多点 <br />通讯，比如多个Client连接一个Server.</p>
		<p>二 什么时候需要考虑粘包问题?</p>
		<p>1:如果利用tcp每次发送数据，就与对方建立连接，然后双方发送完一段数据后，就关闭连接，这样就不会出现粘包问题（因为只有一种包结构,类似于http协议）。关闭连接主要要双方都发送close连接（参考tcp关闭协议）。如：A需要发送一段字符串给B，那么A与B建立连接，然后发送双方都默认好的协议字符如"hello give me sth abour yourself"，然后B收到报文后，就将缓冲区数据接收,然后关闭连接，这样粘包问题不用考虑到，因为大家都知道是发送一段字符。<br />2：如果发送数据无结构，如文件传输，这样发送方只管发送，接收方只管接收存储就ok，也不用考虑粘包<br />3：如果双方建立连接，需要在连接后一段时间内发送不同结构数据，如连接后，有好几种结构：<br />1)"hello give me sth abour yourself" <br />2)"Don't give me sth abour yourself" <br />   那这样的话，如果发送方连续发送这个两个包出去，接收方一次接收可能会是"hello give me sth abour yourselfDon't give me sth abour yourself" 这样接收方就傻了，到底是要干嘛？不知道，因为协议没有规定这么诡异的字符串，所以要处理把它分包，怎么分也需要双方组织一个比较好的包结构，所以一般可能会在头加一个数据长度之类的包，以确保接收。</p>
		<p>三 粘包出现原因：在流传输中出现，UDP不会出现粘包，因为它有消息边界(参考Windows 网络编程)<br />1 发送端需要等缓冲区满才发送出去，造成粘包<br />2 接收方不及时接收缓冲区的包，造成多个包接收</p>
		<p>解决办法：<br />为了避免粘包现象，可采取以下几种措施。一是对于发送方引起的粘包现象，用户可通过编程设置来避免，TCP提供了强制数据立即传送的操作指令push，TCP软件收到该操作指令后，就立即将本段数据发送出去，而不必等待发送缓冲区满；二是对于接收方引起的粘包，则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施，使其及时接收数据，从而尽量避免出现粘包现象；三是由接收方控制，将一包数据按结构字段，人为控制分多次接收，然后合并，通过这种手段来避免粘包。</p>
		<p>以上提到的三种措施，都有其不足之处。第一种编程设置方法虽然可以避免发送方引起的粘包，但它关闭了优化算法，降低了网络发送效率，影响应用程序的性能，一般不建议使用。第二种方法只能减少出现粘包的可能性，但并不能完全避免粘包，当发送频率较高时，或由于网络突发可能使某个时间段数据包到达接收方较快，接收方还是有可能来不及接收，从而导致粘包。第三种方法虽然避免了粘包，但应用程序的效率较低，对实时应用的场合不适合。</p>
		<p>
				<br />相关文章截取：</p>
		<p>一个包没有固定长度，以太网限制在46－1500字节，1500就是以太网的MTU，超过这个量，TCP会为IP数据报设置偏移量进行分片传输，现在一般可允许应用层设置8k（NTFS系）的缓冲区，8k的数据由底层分片，而应用看来只是一次发送。windows的缓冲区经验值是4k,Socket本身分为两种，流(TCP)和数据报(UDP)，你的问题针对这两种不同使用而结论不一</p>
		<p>样。甚至还和你是用阻塞、还是非阻塞Socket来编程有关。</p>
		<p>1、通信长度，这个是你自己决定的，没有系统强迫你要发多大的包，实际应该根据需求和网络状况来决定。对于TCP，这个长度可以大点，但要知道，Socket内部默认的收发缓冲区大小大概是8K，你可以用SetSockOpt来改变。但对于UDP，就不要太大，一般在1024至10K。注意一点，你无论发多大的包，IP层和链路层都会把你的包进行分片发送，一般局域网就是1500左右，广域网就只有几十字节。分片后的包将经过不同的路由到达接收方，对于UDP而言，要是其中一个分片丢失，那么接收方的IP层将把整个发送包丢弃，这就形成丢包。显然，要是一个UDP发包佷大，它被分片后，链路层丢失分片的几率就佷大，你这个UDP包，就佷容易丢失，但是太小又影响效率。最好可以配置这个值，以根据不同的环境来调整到最佳状态。</p>
		<p>send()函数返回了实际发送的长度，在网络不断的情况下，它绝不会返回(发送失败的)错误，最多就是返回0。对于TCP你可以字节写一个循环发送。当send函数返回SOCKET_ERROR时，才标志着有错误。但对于UDP，你不要写循环发送，否则将给你的接收带来极大的麻烦。所以UDP需要用SetSockOpt来改变Socket内部Buffer的大小，以能容纳你的发包。明确一点，TCP作为流，发包是不会整包到达的，而是源源不断的到，那接收方就必须组包。而UDP作为消息或数据报，它一定是整包到达接收方。</p>
		<p>2、关于接收，一般的发包都有包边界，首要的就是你这个包的长度要让接收方知道，于是就有个包头信息，对于TCP，接收方先收这个包头信息，然后再收包数据。一次收齐整个包也可以，可要对结果是否收齐进行验证。这也就完成了组包过程。UDP，那你只能整包接收了。要是你提供的接收Buffer过小，TCP将返回实际接收的长度，余下的还可以收，而UDP不同的是，余下的数据被丢弃并返回WSAEMSGSIZE错误。注意TCP，要是你提供的Buffer佷大，那么可能收到的就是多个发包，你必须分离它们，还有就是当Buffer太小，而一次收不完Socket内部的数据，那么Socket接收事件(OnReceive)，可能不会再触发，使用事件方式进行接收时，密切注意这点。这些特性就是体现了流和数据包的区别。</p>
		<p>
				<br />相关参考文章：<br /><a href="http://www.cnblogs.com/alon/archive/2009/04/16/1437600.html">http://www.cnblogs.com/alon/archive/2009/04/16/1437600.html</a></p>
		<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/binghuazh/archive/2009/05/28/4222516.aspx">http://blog.csdn.net/binghuazh/archive/2009/05/28/4222516.aspx</a></p>
		<p>解决TCP网络传输“粘包”问题</p>
		<p>当前在网络传输应用中，广泛采用的是TCP/IP通信协议及其标准的socket应用开发编程接口（API）。TCP/IP传输层有两个并列的协议：TCP和UDP。其中TCP（transport control protocol，传输控制协议）是面向连接的，提供高可靠性服务。UDP（user datagram protocol，用户数据报协议）是无连接的，提供高效率服务。在实际工程应用中，对可靠性和效率的选择取决于应用的环境和需求。一般情况下，普通数据的网络传输采用高效率的udp，重要数据的网络传输采用高可靠性的TCP。 </p>
		<p>在应用开发过程中，笔者发现基于TCP网络传输的应用程序有时会出现粘包现象（即发送方发送的若干包数据到接收方接收时粘成一包）。针对这种情况，我们进行了专题研究与实验。本文重点分析了TCP网络粘包问题，并结合实验结果提出了解决该问题的对策和方法，供有关工程技术人员参考。</p>
		<p>一、TCP协议简介 </p>
		<p>　　TCP是一个面向连接的传输层协议，虽然TCP不属于iso制定的协议集，但由于其在商业界和工业界的成功应用，它已成为事实上的网络标准，广泛应用于各种网络主机间的通信。</p>
		<p>　　作为一个面向连接的传输层协议，TCP的目标是为用户提供可靠的端到端连接，保证信息有序无误的传输。它除了提供基本的数据传输功能外，还为保证可靠性采用了数据编号、校验和计算、数据确认等一系列措施。它对传送的每个数据字节都进行编号，并请求接收方回传确认信息（ack）。发送方如果在规定的时间内没有收到数据确认，就重传该数据。数据编号使接收方能够处理数据的失序和重复问题。数据误码问题通过在每个传输的数据段中增加校验和予以解决，接收方在接收到数据后检查校验和，若校验和有误，则丢弃该有误码的数据段，并要求发送方重传。流量控制也是保证可靠性的一个重要措施，若无流控，可能会因接收缓冲区溢出而丢失大量数据，导致许多重传，造成网络拥塞恶性循环。TCP采用可变窗口进行流量控制，由接收方控制发送方发送的数据量。</p>
		<p>　　TCP为用户提供了高可靠性的网络传输服务，但可靠性保障措施也影响了传输效率。因此，在实际工程应用中，只有关键数据的传输才采用TCP，而普通数据的传输一般采用高效率的udp。</p>
		<p>二、粘包问题分析与对策</p>
		<p>　　TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包，从接收缓冲区看，后一包数据的头紧接着前一包数据的尾。</p>
		<p>　　出现粘包现象的原因是多方面的，它既可能由发送方造成，也可能由接收方造成。发送方引起的粘包是由TCP协议本身造成的，TCP为提高传输效率，发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少，通常TCP会根据优化算法把这些数据合成一包后一次发送出去，这样接收方就收到了粘包数据。接收方引起的粘包是由于接收方用户进程不及时接收数据，从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区，用户进程从该缓冲区取数据，若下一包数据到达时前一包数据尚未被用户进程取走，则下一包数据放到系统接收缓冲区时就接到前一包数据之后，而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据，这样就一次取到了多包数据（图1所示）。</p>
		<p> <br />图1</p>
		<p> <br />图2</p>
		<p> <br />图3 </p>
		<p>　　粘包情况有两种，一种是粘在一起的包都是完整的数据包（图1、图2所示），另一种情况是粘在一起的包有不完整的包（图3所示），此处假设用户接收缓冲区长度为m个字节。</p>
		<p>　　不是所有的粘包现象都需要处理，若传输的数据为不带结构的连续流数据（如文件传输），则不必把粘连的包分开（简称分包）。但在实际工程应用中，传输的数据一般为带结构的数据，这时就需要做分包处理。</p>
		<p>　　在处理定长结构数据的粘包问题时，分包算法比较简单；在处理不定长结构数据的粘包问题时，分包算法就比较复杂。特别是如图3所示的粘包情况，由于一包数据内容被分在了两个连续的接收包中，处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。</p>
		<p>　　为了避免粘包现象，可采取以下几种措施。一是对于发送方引起的粘包现象，用户可通过编程设置来避免，TCP提供了强制数据立即传送的操作指令push，TCP软件收到该操作指令后，就立即将本段数据发送出去，而不必等待发送缓冲区满；二是对于接收方引起的粘包，则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施，使其及时接收数据，从而尽量避免出现粘包现象；三是由接收方控制，将一包数据按结构字段，人为控制分多次接收，然后合并，通过这种手段来避免粘包。</p>
		<p>　　以上提到的三种措施，都有其不足之处。第一种编程设置方法虽然可以避免发送方引起的粘包，但它关闭了优化算法，降低了网络发送效率，影响应用程序的性能，一般不建议使用。第二种方法只能减少出现粘包的可能性，但并不能完全避免粘包，当发送频率较高时，或由于网络突发可能使某个时间段数据包到达接收方较快，接收方还是有可能来不及接收，从而导致粘包。第三种方法虽然避免了粘包，但应用程序的效率较低，对实时应用的场合不适合。</p>
		<p>　　一种比较周全的对策是：接收方创建一预处理线程，对接收到的数据包进行预处理，将粘连的包分开。对这种方法我们进行了实验，证明是高效可行的。</p>
		<p>三、编程与实现</p>
		<p>　　1．实现框架</p>
		<p>　　实验网络通信程序采用TCP/IP协议的socket api编程实现。socket是面向客户机/服务器模型的。TCP实现框架如图4所示。</p>
		<p>
				<br />图4</p>
		<p>　　2．实验硬件环境：</p>
		<p>　　服务器：pentium 350 微机</p>
		<p>　　客户机：pentium 166微机</p>
		<p>　　网络平台：由10兆共享式hub连接而成的局域网</p>
		<p>　　3．实验软件环境：</p>
		<p>　　操作系统：windows 98</p>
		<p>　　编程语言：visual c++ 5.0</p>
		<p>　　4．主要线程</p>
		<p>　　编程采用多线程方式，服务器端共有两个线程：发送数据线程、发送统计显示线程。客户端共有三个线程：接收数据线程、接收预处理粘包线程、接收统计显示线程。其中，发送和接收线程优先级设为thread_priority_time_critical（最高优先级），预处理线程优先级为thread_priority_above_normal（高于普通优先级），显示线程优先级为thread_priority_normal（普通优先级）。</p>
		<p>　　实验发送数据的数据结构如图5所示：</p>
		<p> </p>
		<p>图5</p>
		<p>　　5．分包算法</p>
		<p>　　针对三种不同的粘包现象，分包算法分别采取了相应的解决办法。其基本思路是首先将待处理的接收数据流（长度设为m）强行转换成预定的结构数据形式，并从中取出结构数据长度字段，即图5中的n，而后根据n计算得到第一包数据长度。</p>
		<p>　　1)若n&lt;m，则表明数据流包含多包数据，从其头部截取n个字节存入临时缓冲区，剩余部分数据依此继续循环处理，直至结束。</p>
		<p>　　2)若n=m，则表明数据流内容恰好是一完整结构数据，直接将其存入临时缓冲区即可。</p>
		<p>　　3)若n&gt;m，则表明数据流内容尚不够构成一完整结构数据，需留待与下一包数据合并后再行处理。</p>
		<p>　　对分包算法具体内容及软件实现有兴趣者，可与作者联系。</p>
		<p>四、实验结果分析</p>
		<p>　　实验结果如下：</p>
		<p>　　1．在上述实验环境下，当发送方连续发送的若干包数据长度之和小于1500b时，常会出现粘包现象，接收方经预处理线程处理后能正确解开粘在一起的包。若程序中设置了“发送不延迟”：（setsockopt (socket_name，ipproto_tcp，tcp_nodelay，(char *) &amp;on，sizeof on) ，其中on=1），则不存在粘包现象。</p>
		<p>　　2．当发送数据为每包1kb～2kb的不定长数据时，若发送间隔时间小于10ms，偶尔会出现粘包，接收方经预处理线程处理后能正确解开粘在一起的包。</p>
		<p>　　3．为测定处理粘包的时间，发送方依次循环发送长度为1.5kb、1.9kb、1.2kb、1.6kb、1.0kb数据，共计1000包。为制造粘包现象，接收线程每次接收前都等待10ms，接收缓冲区设为5000b，结果接收方收到526包数据，其中长度为5000b的有175包。经预处理线程处理可得到1000包正确数据，粘包处理总时间小于1ms。</p>
		<p>　　实验结果表明，TCP粘包现象确实存在，但可通过接收方的预处理予以解决，而且处理时间非常短（实验中1000包数据总共处理时间不到1ms），几乎不影响应用程序的正常工作。</p>
		<p> </p><img src ="http://www.cppblog.com/lapcca/aggbug/126329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-09-10 17:49 <a href="http://www.cppblog.com/lapcca/archive/2010/09/10/126329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 7中的远程桌面增强(Graphics Remoting, Remote Desktop)</title><link>http://www.cppblog.com/lapcca/archive/2010/09/09/126267.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Thu, 09 Sep 2010 14:19:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/09/09/126267.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/126267.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/09/09/126267.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/126267.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/126267.html</trackback:ping><description><![CDATA[08年的夏天，我在<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">微软</strong>总部的一次技术展览会上第一次看到了Windows 7下的<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong>。当时，那位做演示的同事在玩一个非常新的3D游戏，确切地说，他是在远程桌面的窗口中玩3D游戏。我当时就被雷到了！跟那个同事聊了很久，才知道这是Windows 7中会包含的一个新的功能，采用的DirectX重定向和网络压缩等最新的技术，使得通过网络传输的远程桌面，可以流畅的显示和运行多媒体的内容！当时由于Windows 7还在秘密研发阶段，这些内容都不能向外透露。如今Widows 7的beta已经发布，我终于可以跟大家分享一下这个功能的具体细节了！ 
<p></p><p><strong>先看看Windows</strong><strong> 7中的远程桌面给我们带来了些什么新的功能：</strong></p><ul><li>支持Windows 7 Aero效果的3D桌面 
</li><li>支持在<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong>中流畅运行Direct 2D和Direct 3D 10.1的各类应用程序 
</li><li>真正的多显示器支持 
</li><li>远程桌面协议的内核性能增强，包括网络传输的优化和压缩 
</li><li>多媒体增强 
<ul><li>支持Media Foundation 
</li><li>支持DirectShow </li></ul></li><li>支持低延时的音频回放 
</li><li>双向的音频传输 </li></ul><p>接下来，我以<a href="http://channel9.msdn.com/pdc2008/ES21/" target="_blank">PDC上关于RDP的课程</a>为主，分以下几个部分详细的跟大家探讨一些远程桌面的技术和Windows 7中最新的进展。</p><ul><li>RDP协议的发展和应用历程 
</li><li>Windows 7中的RDP设计架构(RDP Graphics Architecture) 
</li><li>应用范围和演示 </li></ul><h4><font color="#800000">RDP协议的发展和应用历程</font></h4><p>RDP是<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong><strong style="COLOR: black; BACKGROUND-COLOR: #ff9999">Protocol</strong>的缩写，这是远程桌面的具体实现协议，<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">微软</strong>在MSDN上公布了RDP的协议细则，据说有差不多2000多页的文档。RDP不是<strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">微软</strong>的专属协议，在Liunx等平台上也有不少实际的应用。如果你对RDP本身感兴趣，可以去看看wikipedia中关于<a href="http://en.wikipedia.org/wiki/Remote_Desktop_Protocol" target="_blank">RDP</a>的描述。RDP在Windows平台下最常见的应用是大家熟悉的远程桌面，其实，除了远程桌面，以RDP为底层的应用还包括：</p><ul><li>Terminal Server 
</li><li><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong></li><li><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong> Assistance 
</li><li>Windows Meeting spaces 
</li><li>Media Center Extenders and XBox 360 
</li><li>SCCM <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong> control 
</li><li>Hyper-V <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong> Control 
</li><li>Windows Live Mesh </li></ul><p>RDP是对网络有密集依赖的应用，它的架构和分层如下：</p><p><a href="http://blogs.technet.com/blogfiles/fyu/WindowsLiveWriter/RemoteDesktop_D84A/image_2.png"><img title="image" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="364" alt="image" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb1.png" width="644" border="0" /></a></p><p>近些年来，随着多媒体、3D应用和用户体验的不断提高，Windows下的远程桌面已经不能满足一些日益增多的需求。为此，Windows 7下的RDP和远程桌面做出了革命性的变化。</p><h4><font color="#800000">Windows 7中的RDP设计架构(RDP Graphics Architecture)</font></h4><p>在Windows 7的RDP设计中，一个非常重要的概念是对3D图像图形的渲染，通常，当我们玩3D游戏时，这些渲染是在本地计算机完成的。在Windows 7的RDP中，3D渲染既可以在本地计算机(我们称为Host机)完成，也可以在运行<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong>的计算机(我们称为Client机)上完成。</p><p>具体的来说：Host机上执行3D渲染时，RDP采用了缓存、压缩等技术确保Demote <strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong>上图像的流畅；在进行Client机的3D渲染时，Host机可以通过GDI, Direct 3D, Media, DWM等3D指令集，把需要渲染的数据包通过RDP传送到Client计算机，由Client计算机的CPU和显卡GPU完成硬件的渲染计算。<br /><a href="http://blogs.technet.com/blogfiles/fyu/WindowsLiveWriter/RemoteDesktop_D84A/image_4.png"><img title="image" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="423" alt="image" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb2.png" width="644" border="0" /></a></p><p>从这张架构图，我们可以看出，在RDP协议的上层，为D2D、DX10.1、DWM、Media App、GDI App等提供了接口。使用这些协议的3D游戏、高清视频播放软件，可以将数据流先通过RDP传送到<strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong>所在的Client计算机，再由Client计算机上的硬件完成渲染和执行。有这样的架构，也就不难理解，为什么可以在远程桌面中流畅的运行3D游戏了！</p><p>大家可能比较感兴趣，什么样的应用是在Host机上完成渲染的，什么样的应用是在Client机上完成渲染的，具体的任务分工如下：</p><p>Host机渲染：</p><ul><li>WPF 
</li><li>Silverlight 
</li><li>Flash 
</li><li>早于Direct3D 10.1版的3D应用 
</li><li>其他的多媒体信息 </li></ul><p>Client机渲染：</p><ul><li>GDI 
</li><li>Direct2D 
</li><li>Direct 3D 10.1版之后的3D应用 
</li><li>在Clieng机上有Codec的，并且是没有进行DRM加密的多媒体视频文件 </li></ul><p>Windows 7中RDP的另一个法宝，就是对网络带宽的充分利用和压缩。相比XP和Vista下的RDP，Windows 7 RDP节省了大约40%的网络开销，具体的测试数据如下：</p><p><a href="http://blogs.technet.com/blogfiles/fyu/WindowsLiveWriter/RemoteDesktop_D84A/image_6.png"><img title="image" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="341" alt="image" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb2.bmp" width="644" border="0" /></a></p><p><a href="http://blogs.technet.com/blogfiles/fyu/WindowsLiveWriter/RemoteDesktop_D84A/image_8.png"><img title="image" style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="367" alt="image" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb3.bmp" width="644" border="0" /></a></p><h4><font color="#800000">应用范围和演示</font></h4><p>我们已经比较清楚，如果想在远程桌面流畅的玩游戏、看电影，必须满足以下的要求：</p><ul><li>客户机和远程计算机都必须是Windows 7或Windows Server 2008 R2以上的版本 
</li><li>如果是2D游戏，需要支持Direct2D；如果是3D游戏，需要支持Direct 3D 10.1 
</li><li>本地计算机上必须有播放电影视频文件对应的Codec 
</li><li>本地计算机的CPU或者显卡应该满足渲染3D和视频的基本要求 </li></ul><p>如果想让自己开发的应用程序支持最新的RDP协议，需要研究一下这三个东西。我对开发的技术不是非常了解，原文照搬如下，大家可以到MSDN里面查一下RDP的具体API。</p><p><strong>Dynamic Virtual Channels APIs</strong></p><ul><li>Client/Server extensibility for RDP 
</li><li>Bi-directional streams that extend RDP 
</li><li>Internal features use same technology </li></ul><p><strong><strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong><strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong> ActiveX APIs</strong></p><ul><li>Host/customize full RDP client in your apps 
</li><li>Usable from web, managed or native code </li></ul><p><strong>RDP Windows <strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">Desktop</strong> Sharing APIs</strong></p><ul><li>RDP Platform for screen sharing 
</li><li>Enables sharing console, multiparty connections 
</li><li>Basis of <strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">Remote</strong> Assistance </li></ul><p>开发人员可以用下面的API来检测应用程序当前时候运行在远程桌面的会话中，并且根据情况进行优化和调整。</p><pre class="csharpcode"><span class="rem">//Managed</span>
System.Windows.Forms.SystemInformation.TerminalServerSession

<span class="rem">//Win32</span>
GetSystemMetrics(SM_REMOTESESSION)</pre><p>关于开发方面我就不深入的讨论了，大家可以看PDC上的<a href="http://channel9.msdn.com/pdc2008/ES21/" target="_blank">有关课程</a>。最后再贴几张网上找到的Windows 7远程桌面的运行效果图：</p><p><img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="181" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb4.bmp" width="240" border="0" /><img height="182" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb6.bmp" width="245" /></p><p><img height="174" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb7.png" width="240" /><img height="172" hspace="0" src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_image_thumb5.bmp" width="240" /></p><div class="postfoot">Posted by <strong>Frank Yu</strong><div><span></span> </div></div><img src ="http://www.cppblog.com/lapcca/aggbug/126267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-09-09 22:19 <a href="http://www.cppblog.com/lapcca/archive/2010/09/09/126267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决跨平台系统的工程文件方案(MPC)</title><link>http://www.cppblog.com/lapcca/archive/2010/09/08/126148.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Wed, 08 Sep 2010 03:57:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/09/08/126148.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/126148.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/09/08/126148.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/126148.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/126148.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span>最近的项目有</span>
						<span>
								<font face="Times New Roman">windows</font>
						</span>
						<span>和</span>
						<span>
								<font face="Times New Roman">solaris</font>
						</span>
						<span>两个版本。其中</span>
						<span>
								<font face="Times New Roman">windows</font>
						</span>
						<span>下用的编译器是</span>
						<span>
								<font face="Times New Roman">visual studio 2005</font>
						</span>
						<span>，</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span>
								<font face="Times New Roman">Solaris</font>
						</span>
						<span>下的是</span>
						<span>
								<font face="Times New Roman">CC</font>
						</span>
						<span>。我们现在的方案是先在</span>
						<span>
								<font face="Times New Roman">visual studio 2005 </font>
						</span>
						<span>下测试通过。然后使用</span>
						<span>
								<font face="Times New Roman">MPC</font>
						</span>
						<span>：</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<font size="3">
						<span>
								<font face="Times New Roman">Make Project Creator </font>
						</span>
						<span>生成</span>
						<span>
								<font face="Times New Roman">vcproj</font>
						</span>
						<span>和</span>
						<span>
								<font face="Times New Roman">solaris</font>
						</span>
						<span>下的</span>
						<span>
								<font face="Times New Roman">makefile</font>
						</span>
						<span>文件。最后再对这两个工程文件进行测试。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<font size="3">
						<span>
								<font face="Times New Roman">MPC</font>
						</span>
						<span>是一个开源项目，采用</span>
						<span>
								<font face="Times New Roman">perl</font>
						</span>
						<span>语言编写。使用</span>
						<span>
								<font face="Times New Roman">MPC</font>
						</span>
						<span>只需写一次</span>
						<span>
								<font face="Times New Roman">mpc</font>
						</span>
						<span>文件即可非常容易的生成</span>
						<span>
								<font face="Times New Roman">vcproj(</font>
						</span>
						<span>支持</span>
						<span>
								<font face="Times New Roman">vc6 – vc9)</font>
						</span>
						<span>文件和</span>
						<span>
								<font face="Times New Roman">makefile</font>
						</span>
						<span>、语法也不复杂。</span>
						<span>
								<font face="Times New Roman">ACE</font>
						</span>
						<span>的工程文件就是用的这个东西。十分适合跨平台的项目。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt">
				<font size="3">
						<span>
								<font face="Times New Roman">MPC</font>
						</span>
						<span>使用</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>在工程根目录下创建</span>
						<span>
								<font face="Times New Roman">MPC/config/MPC.cfg</font>
						</span>
						<span>文件，文件内容为：</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" color="#ff0000" size="3">Default_type=make</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" color="#ff0000" size="3">Dynamic_type=$Test_root/bin/mpcfile,/home/test/MPC</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" color="#ff0000" size="3">Logging=info=1 warn=1</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" color="#ff0000" size="3">Verbose_ordering=1</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>第</span>
						<span>
								<font face="Times New Roman">1</font>
						</span>
						<span>行注明了生成工程文件的类型，在这里是</span>
						<span>
								<font face="Times New Roman">makefile</font>
						</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>第</span>
						<span>
								<font face="Times New Roman">2</font>
						</span>
						<span>行引用了两个地方的</span>
						<span>
								<font face="Times New Roman">project</font>
						</span>
						<span>定义</span>
						<span>
								<font face="Times New Roman">(</font>
						</span>
						<span>即</span>
						<span>
								<font face="Times New Roman">MPC</font>
						</span>
						<span>文件</span>
						<span>
								<font face="Times New Roman">)</font>
						</span>
						<span>，有了这一行，则工程文件中任意位置的</span>
						<span>
								<font face="Times New Roman">mpc</font>
						</span>
						<span>文件都可以引用上面两个地方</span>
						<span>
								<font face="Times New Roman">(</font>
						</span>
						<span>包含子目录</span>
						<span>
								<font face="Times New Roman">)</font>
						</span>
						<span>的</span>
						<span>
								<font face="Times New Roman">mpc</font>
						</span>
						<span>或</span>
						<span>
								<font face="Times New Roman">mpb</font>
						</span>
						<span>文件了。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>
								<font face="Times New Roman">mpc</font>
						</span>
						<span>文件是可以继承的。示例如下：</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" size="3">project(mod1):modob{</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>exename=”mod1”</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>exeout=”../../bin”</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>includes+=”../../include/mod1”</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<span style="mso-tab-count: 1">
								<font face="Times New Roman" size="3">       </font>
						</span>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>Source_Files{</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 2">              </span>*.cpp</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>}</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>Header_Files{</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 2">              </span>*.h</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>}</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" size="3">}</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>其中</span>
						<span>
								<font face="Times New Roman">exename</font>
						</span>
						<span>为生成文件的名称，</span>
						<span>
								<font face="Times New Roman">exeout</font>
						</span>
						<span>为生成的文件的路径，</span>
						<span>
								<font face="Times New Roman">includes</font>
						</span>
						<span>为头文件包含的路径。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>还有libout(lib文件输出路径), dllout(动态链接库输出路径), sharedname(动态链接库名称)</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>
								<font face="Times New Roman">Mpb</font>
						</span>
						<span>文件主要是用来描述一些公共的信息</span>
						<span>
								<font face="Times New Roman">(</font>
						</span>
						<span>如公共头文件，动态库</span>
						<span>
								<font face="Times New Roman">)</font>
						</span>
						<span>，如：</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman" size="3">Project {</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>Includes += ../../include/common</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">
										<span style="mso-tab-count: 1">       </span>Libpaths+=”../../lib”</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font face="Times New Roman">
								<font size="3">}</font>
						</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<font size="3">
						<span>完成上面文件之后，输入命令：</span>
						<span>
								<font face="Times New Roman">mwc.pl</font>
						</span>
						<span>即可生成工程文件</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font color="#ff0000" size="3">注意：在路径中切不可包含空格</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font color="#000000" size="3">mwc.pl -static 生成静态库</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font color="#000000" size="3">在MPC文件中可以加上 avoids += shared</font>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt">
				<span>
						<font color="#000000" size="3">这样就能避免生成动态的工程了(exe或dll)<br /></font>
				</span>
		</p>
		<hr />
		<h1 class="firstHeading">MPC使用介绍</h1>
		<div id="bodyContent">
				<h3 id="siteSub">
						<div id="jump-to-nav"> </div>
						<div>MPC是<em>ACE</em>中附带的一个很有用的Makefile工具，简单的说MPC可以通过一个单一的定义文件，生成各种开发环境需要的Makefile,VC工程文件，并且可以通过自行扩展适合各种开发环境需要的工程文件。 </div>
				</h3>
				<a name=".E7.BC.96.E5.86.99.E4.B8.80.E4.B8.AAMWC.E5.92.8CMPC.E6.96.87.E4.BB.B6">
				</a>
				<h2>
						<span class="mw-headline">编写一个MWC和MPC文件</span>
				</h2>
				<p>hello.mwc例子 </p>
				<pre class="c c" style="FONT-FAMILY: monospace">
						<span style="COLOR: #666666; FONT-STYLE: italic">// -*- MPC -*-</span>
workspace <span style="COLOR: #009900">{</span>
  hello.<span style="COLOR: #202020">mpc</span><span style="COLOR: #009900">}</span></pre>
				<p>hello.mpc例子 </p>
				<pre class="c c" style="FONT-FAMILY: monospace">
						<span style="COLOR: #666666; FONT-STYLE: italic">// -*- MPC -*-</span>
project<span style="COLOR: #009900">(</span>hello<span style="COLOR: #009900">)</span><span style="COLOR: #339933">:</span>aceexe<span style="COLOR: #339933">,</span> acexml<span style="COLOR: #339933">,</span> avoids_ace_for_tao <span style="COLOR: #009900">{</span>
  exename <span style="COLOR: #339933">=</span> hello
  avoids <span style="COLOR: #339933">+=</span> uses_wchar
 
  Source_Files <span style="COLOR: #009900">{</span>
    hello.<span style="COLOR: #202020">cpp</span><span style="COLOR: #009900">}</span><span style="COLOR: #009900">}</span></pre>
				<p>mwc可以看作是workspace定义，mpc可以看作是project定义，一个workspace可以包含多个project，并且可以定义多个project之间的依赖关系，详细的语法可以参考后面提供的参考资料。 </p>
				<a name=".E7.94.9F.E6.88.90Makefile">
				</a>
				<h2>
						<span class="mw-headline">生成Makefile</span>
				</h2>
				<p>生成Makefile </p>
				<pre>$ACE_ROOT/bin/mwc.pl -type make hello.mwc
</pre>
				<p>生成VC2008工程文件 </p>
				<pre>$ACE_ROOT/bin/mwc.pl -type vc9 hello.mwc
</pre>
				<p>同时生成多个工程文件 </p>
				<pre>$ACE_ROOT/bin/mwc.pl -type make -type vc9 hello.mwc
</pre>
				<p>同时生成vc9的静态和动态库工程文件，并且通过工程名称予以区别 </p>
				<pre>$ACE_ROOT/bin/mwc.pl -type vc9 -ti lib:vc9lib -name_modifier *_lib_vc9 hello.mwc
</pre>
		</div><img src ="http://www.cppblog.com/lapcca/aggbug/126148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-09-08 11:57 <a href="http://www.cppblog.com/lapcca/archive/2010/09/08/126148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>百度自动登陆代码实现</title><link>http://www.cppblog.com/lapcca/archive/2010/07/27/121374.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Tue, 27 Jul 2010 01:31:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/07/27/121374.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/121374.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/07/27/121374.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/121374.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/121374.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1												/**/										/*						************open_login_page.c**********						*/																						  2										#include 				&lt;				stdio.h				&gt;									...&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/07/27/121374.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/121374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-07-27 09:31 <a href="http://www.cppblog.com/lapcca/archive/2010/07/27/121374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IP协议族协议头结构</title><link>http://www.cppblog.com/lapcca/archive/2010/07/27/121372.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Tue, 27 Jul 2010 01:27:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/07/27/121372.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/121372.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/07/27/121372.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/121372.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/121372.html</trackback:ping><description><![CDATA[<p>//IP协议族协议头结构(含 c声明 和 rfc 字符图示) <br />//Jurassic 2003.3.6 created. <br />/*++ <br />TCP Header Format <br />                                     <br />    0                   1                   2                   3    <br />    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |          Source Port          |       Destination Port        | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                        Sequence Number                        | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                    Acknowledgment Number                      | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |  Data |           |U|A|P|R|S|F|                               | <br />   | Offset| Reserved  |R|C|S|S|Y|I|            Window             | <br />   |       |           |G|K|H|T|N|N|                               | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |           Checksum            |         Urgent Pointer        | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                    Options                    |    Padding    | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                             data                              | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                            TCP Header Format <br />RFC-793 <br />--*/ <br />typedef  <br />struct _tcphdr <br />{ <br />unsigned short source; //原端口地址 <br />unsigned short dest; //目的端口地址 <br />unsigned long seq; //序号 <br />unsigned long ack_seq; //确认号 <br />unsigned short doff:4; //首部长度 <br />unsigned short resl:4; //保留 <br />unsigned short cwr:1; //控制 <br />unsigned short ece:1; <br />unsigned short urg:1; <br />unsigned short ack:1; <br />unsigned short psh:1; <br />unsigned short rst:1; <br />unsigned short syn:1; <br />unsigned short fin:1; <br />unsigned short window; <br />unsigned short check; <br />unsigned short urg_ptr;}tcphdr; </p>
		<p>/*++ <br />IP Header Format    0                   1                   2                   3    <br />    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |Version|  IHL  |Type of Service|          Total Length         | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |         Identification        |Flags|      Fragment Offset    | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |  Time to Live |    Protocol   |         Header Checksum       | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                       Source Address                          | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                    Destination Address                        | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                    Options                    |    Padding    | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+IP Header FormatRFC-791                             <br />--*/ <br />typedef <br />struct _iphdr <br />{ <br />unsigned char version:4; //版本 <br />unsigned char ihl:4; //首部长度 <br />unsigned char tos; //服务类型 <br />unsigned short tot_len; //总长度 <br />unsigned short id; //标志 <br />unsigned short frag_off; //分片偏移 <br />unsigned char ttl; //生存时间 <br />unsigned char protocol; //协议 <br />unsigned char check; //检验和 <br />unsigned long saddr; //源IP地址 <br />unsigned long daaddr; //目的IP地址 <br />}iphdr; <br />/*++ <br />UDP Header Format <br />                  0      7 8     15 16    23 24    31  <br />                 +--------+--------+--------+--------+ <br />                 |          source address           | <br />                 +--------+--------+--------+--------+ <br />                 |        destination address        | <br />                 +--------+--------+--------+--------+ <br />                 |  zero  |protocol|   UDP length    | <br />                 +--------+--------+--------+--------+ </p>
		<p>UDP Header Format <br />RFC-768 <br />--*/ <br />typedef <br />struct _udphdr <br />{ <br />unsigned short source; <br />unsigned short dest; <br />unsigned short len; <br />unsigned short check;}udphdr; <br />/*++ <br />ICMP Header Format    0                   1                   2                   3 <br />    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |     Type      |     Code      |          Checksum             | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |                             unused                            | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |      Internet Header + 64 bits of Original Data Datagram      | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ICMP Header FormatRFC-792 <br />--*/ <br />typedef <br />struct _icmphdr <br />{ <br />unsigned char type; //类型 <br />unsigned char code; //代码 <br />unsigned short checksum; //校验和 <br />union <br />{ <br />struct  <br />{ <br />unsigned short id; //标识符 <br />unsigned short sequence; //序号 <br />}echo; </p>
		<p>unsigned long gateway; //目标路由器的IP地址 </p>
		<p>struct  <br />{ <br />unsigned short unused; // <br />unsigned short mtu; <br />}frag; <br />} un;}icmphdr; </p>
		<p>/*++ <br />IGMP Header Format    0                   1                   2                   3     <br />    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1   <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  <br />   |     Type      |     Code      |           Checksum            |  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  <br />   |                          Identifier                           |  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  <br />   |                         Group Address                         |  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  <br />   |                                                               |  <br />   +                         Access Key                            +  <br />   |                                                               |  <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  </p>
		<p>IGMP Header FormatRFC-988 <br />--*/ <br />typedef <br />struct _igmphdr <br />{ <br />unsigned char type; <br />unsigned char code; /* For newer IGMP */ <br />unsigned short csum; <br />unsigned long group;}igmphdr; </p>
		<p>/*++ <br />IPv6 Header Format   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   | Ver.  | IHL   |   TOS         |   Total Length                | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |     Identification            |Flags|   Fragment Offset       | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |1|1|1|1|1|0| Offset| Reserved  | Source IP address part 1      | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   |1|1|1|1|1|0| Offset| Reserved  | Destination IP address part 1 | <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   :                            Options                            : <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   : SADDR Code    |Len adr. part 2| Source IP address part 2      : <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   : DADDR Code    |Len adr. part 2| Destination IP address part 2 : <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ <br />   :                            Data                               : <br />   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+IPv6 Header Format   RFC-1365 <br />--*/ <br />typedef <br />struct _ipv6hdr <br />{ <br />unsigned char version:4; <br />unsigned char priority:4; <br />unsigned char flow_lbl[3]; <br />unsigned short payload_len; <br />unsigned char nexthdr; <br />unsigned char hop_limit; <br />//struct in6_addr saddr; <br />//struct in6_addr daddr;}ipv6hdr; <br />[/code] <br />当然，为了口中餐，为了未来贴身mm，为了给她备房备车：），不得不停了下来。 <br />下面的是未整理的结构。有时间的话，我会继续整理，也欢迎网友补充。[code] <br />/* <br /> * This is an Ethernet frame header. <br /> */ <br />typedef  <br />struct _ethhdr  <br />{ <br />//unsigned char h_dest[ETH_ALEN]; // destination eth addr <br />//unsigned char h_source[ETH_ALEN]; // source ether addr <br />//unsigned short h_proto; // packet type ID field}ethhdr; <br />// FDDI <br />/* Define 802.2 Type 1 header */ <br />//struct fddi_8022_1_hdr <br />// { <br />// __u8 dsap; /* destination service access point */ <br />// __u8 ssap; /* source service access point */ <br />// __u8 ctrl; /* control byte #1 */ <br />// } __attribute__ ((packed)); <br />// <br />///* Define 802.2 Type 2 header */ <br />//struct fddi_8022_2_hdr <br />// { <br />// __u8 dsap; /* destination service access point */ <br />// __u8 ssap; /* source service access point */ <br />// __u8 ctrl_1; /* control byte #1 */ <br />// __u8 ctrl_2; /* control byte #2 */ <br />// } __attribute__ ((packed)); <br />// <br />///* Define 802.2 SNAP header */ <br />//#define FDDI_K_OUI_LEN 3 <br />//struct fddi_snap_hdr <br />// { <br />// __u8 dsap; /* always 0xAA */ <br />// __u8 ssap; /* always 0xAA */ <br />// __u8 ctrl; /* always 0x03 */ <br />// __u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */ <br />// __u16 ethertype; /* packet type ID field */ <br />// } __attribute__ ((packed)); <br />// <br />///* Define FDDI LLC frame header */ <br />//struct fddihdr <br />// { <br />// __u8 fc; /* frame control */ <br />// __u8 daddr[FDDI_K_ALEN]; /* destination address */ <br />// __u8 saddr[FDDI_K_ALEN]; /* source address */ <br />// union <br />// { <br />// struct fddi_8022_1_hdr llc_8022_1; <br />// struct fddi_8022_2_hdr llc_8022_2; <br />// struct fddi_snap_hdr llc_snap; <br />// } hdr; <br />// } __attribute__ ((packed)); </p><img src ="http://www.cppblog.com/lapcca/aggbug/121372.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-07-27 09:27 <a href="http://www.cppblog.com/lapcca/archive/2010/07/27/121372.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOL_SOCKET、IPPROTO_IP、IPPROTO_TCP和NSPROTO_IPX选项级别 </title><link>http://www.cppblog.com/lapcca/archive/2010/05/07/114727.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 07 May 2010 02:49:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/05/07/114727.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/114727.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/05/07/114727.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/114727.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/114727.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: int																																																																												PASCAL																																																																																									...&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/05/07/114727.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/114727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-05-07 10:49 <a href="http://www.cppblog.com/lapcca/archive/2010/05/07/114727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>支持VC6.0的SDK包</title><link>http://www.cppblog.com/lapcca/archive/2010/04/15/112679.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Thu, 15 Apr 2010 08:41:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/04/15/112679.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/112679.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/04/15/112679.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/112679.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/112679.html</trackback:ping><description><![CDATA[<p>Windows Server 2003 PSDK February 2003 Edition，可以和VC6一起使用、并支持各种目标OS的最后一个版本的SDK。<a href="http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm">http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm</a></p>
		<p>This edition of the SDK supports development for the following platforms: <br />Windows Server 2003 <br />Windows Advanced Server, Limited Edition <br />Windows XP <br />Windows XP 64-bit Edition <br />Windows 2000 <br />Windows NT versions 3.51 and 4.0 <br />Windows Millennium Edition <br />Windows 95 and Windows 98 </p>
		<p>XPSP2 August 2004 Edition，可以在VC6使用，开发针对XPSP2的特殊功能的程序，可以和上面的一道使用，但请安装在不同目录。<a href="http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm">http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm</a></p>
		<p>Newly released: The Platform SDK for Windows XP Service Pack 2 support <br />(includes MDAC 2.8, Tablet 1.7 and Windows Installer 3.0) <br />The XPSP2 version of the Platform SDK was developed to work either side by <br />side with the Windows Server 2003 SDK or standalone but will not provide <br />build environments for: <br />Windows Server 2003 <br />Windows Advanced Server, Limited Edition <br />Windows XP <br />Windows XP 64-bit Edition <br />Windows 2000 <br />Windows NT versions 3.51 and 4.0 <br />Windows Millennium Edition <br />Windows 95 and Windows 98 <br />You must install The Microsoft Platform Software Development Kit (SDK) for <br />Windows Server 2003 for those environments.The SDKs can not be installed in <br />the same directory for side by side performance. </p>
		<p>
				<br />Windows Server 2003 SP1 Platform SDK Web Install，最新版的SDK，可惜不能和VC6一起协作，不再支持NT4和9X。<a href="http://www.microsoft.com/downloads/details.aspx?familyid=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&amp;displaylang=en</a></p>
		<p>This edition of the SDK replaces the previous SDKs for Windows XP SP2 and Windows Server 2003 and can be used to develop applications for those platforms. <br />Supported Operating Systems: Windows 2000; Windows Server 2003; Windows XP 64-bit; Windows XP Professional Edition ; Windows XP Service Pack 1 <br />This SDK does not support working with Microsoft Visual C/C 6.0 as support for VC 6.0 has ended. The last SDK that will work with VC 6.0 is the February 2003 Edition.</p>
		<p> </p>
		<p> </p>
		<p>vc6快10岁了，呵呵，蛮经典的东西。 <br />以下SDK和库都是能在VC6下使用。它们之间各自有各自的功能，不需要比较，除非是相同类型的库，例如XML解析器，我才比较一下，排名也不分先后，并且描述的简略不代表个人的感情色情。很多库我都喜欢，但我只是简单说两句。例如MFC，STL，ICE等等。希望大家的开发效率能提高不少。有些库或者SDK没有罗列其中，大家可以补上。 </p>
		<p>Windows server 2003 r2 SDK(最新的Windows SDK是Vista版的) <br />提供最新操作系统的API接口，支持Windows2003r2以及以前的系统，如果想使用一些平台特性，这开发包是必备的。 <br /><a href="http://www.microsoft.com/downloads/info.aspx?na=22&amp;p=22&amp;SrcDisplayLang=en&amp;SrcCategoryId=&amp;SrcFamilyId=&amp;u=%2fdownloads%2fdetails.aspx%3fFamilyID%3de15438ac-60be-41bd-aa14-7f1e0f19ca0d%26DisplayLang%3den">http://www.microsoft.com/downloads/info.aspx?na=22&amp;p=22&amp;SrcDisplayLang=en&amp;SrcCategoryId=&amp;SrcFamilyId=&amp;u=%2fdownloads%2fdetails.aspx%3fFamilyID%3de15438ac-60be-41bd-aa14-7f1e0f19ca0d%26DisplayLang%3den</a><br />SDK属于Visual C++的一部分,但其自带的版本较老,已经不适合一些产品了,例如WinXP等.该SDK包含以下MS产品的SDK: <br />Windows,Office,Windows Script(这个应该算是个产品吧..WScript/CScript),netmeeting,IIS, Internet Explorer,MS XML,GDI+,Windows Media Services,DirectShow... <br />包含以下的程序库:ATL,MFC,OpenGL... <br />更多信息请查看SDK或者MSDN自带的帮助目录. </p>
		<p>netmeeting SDK <br />想将远程桌面,多人会议,视频,文件传送,电子白板功能嵌入到你的程序或者网站中吗?用它就没错了. <br />内含在Windows server 2003 r2 SDK </p>
		<p>Internet Explorer SDK <br />可以用它来解析网页，从而开发出自己特别的需求的“新浏览器”，也可以扩展IE。遨游，TT等外壳浏览器就属于这类应用。QZONE也属于，新版本的QZONE是采用自动化的方式去扩展。 <br />内含在Windows SDK里。 </p>
		<p>WMEncoderSDK <br />Windows Media编码器的开发包，可以从影像捕捉设备或桌面画面录制，亦提供文件格式转换的功能。 <br />------------ <br />是一套容易使用，而且功能强大的软件，提供使用者自行录制影像的功能，可以从影像捕捉设备或桌面画面录制，亦提供文件格式转换的功能。主要的特色在于容易使用、高品质编码、增强的可程序化与管理，特点为：新的使用者界面和向导，更容易设定与制作影片，用来提供网络现场播放或需求播放，并支持多重来源，可以立即切换来源，并可监视编码程序进行时的资料，如影像大小、资料流量等等。新的编码能力，支持de-interlacing、inverse telecine和屏幕捕捉，能有更好的输出品质，能从320*240*60fps到640*480*30fps，捕捉文件最大可到30GB，支持的捕捉设备包括Winnov、ATI、Hauppauge，以及USB视讯摄影机等。Windows Media Encoder SDK提供网站开发者全自动的编码控制，可从网络（LAN）远端控制，或透过API存取或ASP控制 <br />---------------- <br /><a href="http://www.microsoft.com/downloads/details.aspx?familyid=5691BA02-E496-465A-BBA9-B2F1182CDF24&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=5691BA02-E496-465A-BBA9-B2F1182CDF24&amp;displaylang=en</a></p>
		<p>WMPlayerSDK <br />为Windows Media Player开发插件或者调用其组件的开发包。 <br /><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e43cbe59-678a-458a-86a7-ff1716fad02f&amp;DisplayLang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=e43cbe59-678a-458a-86a7-ff1716fad02f&amp;DisplayLang=en</a></p>
		<p>detours <br />Microsoft自己出的一个PE镜像操作包，可以轻松实现API Hook,修改IAT等。 <br /><a href="http://research.microsoft.com/research/downloads/Details/10E5D78C-592C-419D-A53E-BAE8DBD81801/Details.aspx">http://research.microsoft.com/research/downloads/Details/10E5D78C-592C-419D-A53E-BAE8DBD81801/Details.aspx</a></p>
		<p>WTL(Windows Template Library) <br />一个基于模板技术、简洁而又完整的界面库，能生成小巧的应用程序，厌倦了庞大的MFC，可以考虑使用它来开发界面，除了对界面提供支持，还提供了一系列的辅助类，例如：CString,CFindFile等。8.0支持WinCE，以及Vista的特性。 <br /><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e5ba5ba4-6e6b-462a-b24c-61115e846f0c&amp;DisplayLang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=e5ba5ba4-6e6b-462a-b24c-61115e846f0c&amp;DisplayLang=en</a></p>
		<p>DirectX SDK <br />能出色地完成高速的实时动画渲染、交互式音乐与环境音效、高效多媒体数据处理等任务。Windows下游戏开发一般使用它。 <br /><a href="http://www.microsoft.com/downloads/details.aspx?familyid=4b78a58a-e672-4b83-a28e-72b5e93bd60a&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?familyid=4b78a58a-e672-4b83-a28e-72b5e93bd60a&amp;displaylang=en</a></p>
		<p>DDK/IFS DDK(Windows Driver Development Kit) <br />用于开发Windows驱动程序的开发包,装了它VC也能开发驱动程序，不过推荐使用DDK带的build工具进行编译。IFS DDK可以开发文件系统驱动。 <br /><a href="http://www.microsoft.com/whdc/devtools/ddk/default.mspx">http://www.microsoft.com/whdc/devtools/ddk/default.mspx</a></p>
		<p>MS CHART <br />可以在程序里面画出专业的柱状图，曲线图等专业的统计图形。 <br />内含在VB或者office的安装包里。 </p>
		<p>ATL <br />用于开发COM的一个框架，有了它，写COM就轻松很多了。除了对COM的支持，还提供了CImage(GDI+的包装类，很好用)、CRegKey(注册表的支持)、CAtlRegExp(正则表达式)等。 <br />VC自带或者包含在Windows SDK中 </p>
		<p>GDI+ SDK <br />GDI+是Microsoft的新的图形编程接口,具有简单、易用等特性。支持多种图象格式，不必再为jpg,gif等格式解码而发愁。对比GDI，有以下新特性，支持渐变画刷、对立的路径对象、矩阵对象、多种图片格式等。WinXP以及以上系统自带Gdi+所需的DLL。 <br />包含在新版Visual Studio或者包含在Windows SDK中 </p>
		<p>CxImage <br />一套图象操作代码,支持多种格式:包括bmp,jpg,png,gif(静态和动态都支持),wbmp,tif,wmf,pcx,tga,ico等.基于GDI的操作而不是GDI+.并提供了一系列的算法,例如缩放,旋转,灰度等等. <br /><a href="http://www.xdp.it/">http://www.xdp.it</a></p>
		<p>MFC <br />一个非常老(比VC6还老)而且优秀的程序框架，是对Windows API源码级的封装，有不少的优秀软件就是用它写的。 <br />包含在Visual Studio中 </p>
		<p>Xtreme ToolkitPro/BCGControlBar Professional <br />非常优秀MFC扩展库,用于界面开发,它们提供了仿Office,Visual Studio等MS产品外观的控件. <br />Xtreme有免费版本CJLibrary <a href="http://www.codejock.com/">http://www.codejock.com/</a><br />BCG在VS2008里是MFC的一部分了,http://www.bcgsoft.com/ </p>
		<p>WFC(Win32 Foundation Classes) <br />一个MFC扩展库,封装了那些MFC没有封装的Win32 API..例如:CDesktop,CMixer,CRegistry等等 <br /><a href="http://www.codeproject.com/library/wfc.asp">http://www.codeproject.com/library/wfc.asp</a></p>
		<p>Microsoft Speech SDK <br />文本朗读和语音识别的开发包。也支持中文发音。 <br /><a href="http://www.microsoft.com/speech">http://www.microsoft.com/speech</a><br /><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;DisplayLang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&amp;DisplayLang=en</a></p>
		<p>
				<br />MS Agent <br />WinXP搜索里的那只黄色小狗或者Office2003里面的助手就是MS Agent，用这个开发包就可以控制他们。 <br />包含在Visual Studio或者包含在Windows SDK中 </p>
		<p>MS XML/tinyXML <br />用于解析XML文件的开发包。 <br />MS XML功能强大,对中文有完美的支持. <br />tinyXML体积小,带源代码. <br />(其它XML解析器都不怎么好,IBM的XML4C功能虽强,可是它的DLL有12M那么大,Xerces c++不能支持中文,Libxml要支持中文的话需要自己写转换函数) <br />MS XML:http://www.microsoft.com/downloads/details.aspx?FamilyID=993c0bcf-3bcf-4009-be21-27e85e1857b1&amp;DisplayLang=en <br />tinyXML:www.sourceforge.net/projects/tinyxml </p>
		<p>OpenGL <br />是个专业的3D程序接口，是一个功能强大，调用方便的底层3D图形库。OpenGL是个与硬件无关的软件接口，可以在不同的平台工作。 <br />包含在Visual Studio或者包含在Windows SDK中 </p>
		<p>
				<br />STL <br />非常优秀的C++标准库,提供数据容器以及通用算法等的C++库. <br />包含在Visual Studio </p>
		<p>Boost <br />一套开放源代码、高度可移植的C++库,提供数值计算、泛型编程、元编程、平台API等支持。常用的有Regex，Lambda，smart_ptr等等 <br /><a href="http://www.boost.org/">http://www.boost.org</a></p>
		<p>WinPcap <br />最常用的就是用它来捕获网络封包。很多网络程序，以前用过的一个电信的拨号器，Ethereal等都是使用这个。 <br /><a href="http://winpcap.polito.it/">http://winpcap.polito.it</a></p>
		<p>zLib <br />一个开源的数据无损压缩库.最方便的是它可以压缩内存缓冲,而且速度快,很多网络游戏都使用了它压缩数据包. <br /><a href="http://www.gzip.org/zlib/">http://www.gzip.org/zlib/</a></p>
		<p>
				<br />Xvid/Divx <br />视频编码/解码库.(Divx是个商业产品,Xvid是个开源项目) <br /><a href="http://www.xvid.org/">www.xvid.org</a></p>
		<p>ACE/ICE <br />ACE全称adaptive communication enviroment，是一套C++的通信库。它提供了socket/threading/memory management等多种系统调用的面对对象的wrapper,使C++通信软件开发更加简单。 <br />ICE(Internet Communications Engine)一种现代的面向对象中间件，可用于替代像CORBA或COM/DCOM/COM+这样的中间件，特点是开发简易，运行效率高。可以开发出电信级别的应用。 <br />ACE:http://www.cs.wustl.edu/~schmidt/ACE.html <br />ICE:http://www.zeroc.com/ </p>
		<p>crypto++ <br />实现了各种公开密钥算法、对称加密算法、数字签名算法、信息摘要算法以及其相关的其它密码算法等等.其实我只用里面的md5,crc32和aes. <br /><a href="http://sourceforge.net/projects/cryptopp">http://sourceforge.net/projects/cryptopp</a></p>
		<p>WxWindows (跨平台的GUI库) <br />类层次极像MFC,通过多年的开发也是一个日趋完善的GUI库,完全开放源代码的。 <br /><a href="http://www.wxwindows.org/">http://www.wxwindows.org/</a></p>
		<p>blitz (高效率的数值计算函数库) <br />Blitz++ 是一个高效率的数值计算函数库，它的设计目的是希望建立一套既具像C++ 一样方便，同时又比Fortran速度更快的数值计算环境。 <br /><a href="http://folk.uio.no/patricg/blitz/html/index.html">http://folk.uio.no/patricg/blitz/html/index.html</a></p><img src ="http://www.cppblog.com/lapcca/aggbug/112679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-04-15 16:41 <a href="http://www.cppblog.com/lapcca/archive/2010/04/15/112679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞(转载)</title><link>http://www.cppblog.com/lapcca/archive/2010/01/29/106718.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 29 Jan 2010 04:55:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/01/29/106718.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/106718.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/01/29/106718.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/106718.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/106718.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这个标题用了两个顿号三个名称，其实说得是同一个东西，只是网上有不同的说法罢了，另外好像还有人叫TCP打孔（我的朋友小妞听说后问“要打孔啊，要不要我帮你去借个电钻过来啊？”“~！·￥%……·！”）。<br>闲话少说，我们先看一下技术背景：<br>Internet的迅速发展以及IPv4 地址数量的限制使得网络地址翻译(NAT,Network Address Trans2lation)设备得到广泛应用。NAT设备允许处于同一NAT后的多台主机共享一个公网(本文将处于同一NAT后的网络称为私网,处于NAT前的网络称为公网) IP 地址。一个私网IP 地址通过NAT设备与公网的其他<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/01/29/106718.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/106718.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-01-29 12:55 <a href="http://www.cppblog.com/lapcca/archive/2010/01/29/106718.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么叫打洞</title><link>http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Thu, 28 Jan 2010 11:26:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/106663.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/106663.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/106663.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 确切地说是穿透NAT，一般使用ＵＤＰ协议，ＴＣＰ协议也可以穿透，只是好像没有UDP成功率高。&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/106663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-01-28 19:26 <a href="http://www.cppblog.com/lapcca/archive/2010/01/28/106663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STUN, STUNT, XSTUNT 介绍</title><link>http://www.cppblog.com/lapcca/archive/2010/01/27/106561.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Wed, 27 Jan 2010 15:10:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/01/27/106561.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/106561.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/01/27/106561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/106561.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/106561.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: STUN（Simple Traversal of User Datagram Protocol through Network Address Translators (NATs)，NAT的UDP简单穿越）是一种网络协议，它允许位于NAT（或多重NAT）后的客户端找出自己的公网地址，查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT 路由器之后的主机之间建立UDP通信。该协议由RFC 3489定义<br>一旦客户端得知了Internet端的UDP端口，通信就可以开始了。如果NAT是完全圆锥型的，那么双方中的任何一方都可以发起通信。如果NAT是受限圆锥型或端口受限圆锥型，双方必须一起开始传输。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/01/27/106561.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/106561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-01-27 23:10 <a href="http://www.cppblog.com/lapcca/archive/2010/01/27/106561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>