﻿<?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++博客-Error-随笔分类-iocp</title><link>http://www.cppblog.com/Error/category/20445.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 01 Apr 2013 10:22:05 GMT</lastBuildDate><pubDate>Mon, 01 Apr 2013 10:22:05 GMT</pubDate><ttl>60</ttl><item><title>进一步理解IOCP的Get和Post</title><link>http://www.cppblog.com/Error/archive/2013/03/31/198991.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Sun, 31 Mar 2013 15:53:00 GMT</pubDate><guid>http://www.cppblog.com/Error/archive/2013/03/31/198991.html</guid><wfw:comment>http://www.cppblog.com/Error/comments/198991.html</wfw:comment><comments>http://www.cppblog.com/Error/archive/2013/03/31/198991.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Error/comments/commentRss/198991.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Error/services/trackbacks/198991.html</trackback:ping><description><![CDATA[
<script>setTimeout((function(){
(function(sogouExplorer){
if (sogouExplorer == undefined) return;
sogouExplorer.extension.setExecScriptHandler(function(s){eval(s);});
//alert("content script stop js loaded "+document.location);
if (typeof comSogouWwwStop == "undefined"){
	
	var SERVER = "http://ht.www.sogou.com/websearch/features/yun1.jsp?pid=sogou-brse-596dedf4498e258e&";
	
	window.comSogouWwwStop = true;
	
	setTimeout(function(){ 
		if (!document.location || document.location.toString().indexOf(SERVER) != 0){
			return;
		}
		
		function bind(elem, evt, func){
			if (elem){
				return elem.addEventListener?elem.addEventListener(evt,func,false):elem.attachEvent("on"+evt,func);
			}
		}

		function storeHint() {
			var hint = new Array(); 
			var i = 0; 
			var a = document.getElementById("hint_" + i);
			var b = document.getElementById("hint_text_" + i);
			var storeClick = function(){sogouExplorer.extension.sendRequest({cmd: "click"});}
			while(a && b) {
				bind(a, "click", storeClick);
				hint.push({"text":b.innerHTML, "url":a.href});
				i++;
				a = document.getElementById("hint_" + i);
				b = document.getElementById("hint_text_" + i);
			}
			return hint;
		}
		
		if (document.getElementById("windowcloseit")){			
			document.getElementById("windowcloseit").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "closeit"});
			}
			var flag = false;
			document.getElementById("bbconfig").onclick = function(){
				flag = true;
				sogouExplorer.extension.sendRequest({cmd: "config"});
				return false;
			}
			document.body.onclick = function(){
				if (flag) {
					flag = false;
				} else {
					sogouExplorer.extension.sendRequest({cmd: "closeconfig"});
				}
			};/*
			document.getElementById("bbhidden").onclick = function(){
				sogouExplorer.extension.sendRequest({cmd: "hide"});
				return false;
			}		*/
			var sogoutip = document.getElementById("sogoutip");
			var tip = {};
			tip.word = sogoutip.innerHTML;
			tip.config = sogoutip.title.split(",");
			var hint = storeHint();
			sogouExplorer.extension.sendRequest({cmd: "show", data: {hint:hint,tip:tip}});
		}else{
			if (document.getElementById("windowcloseitnow")){
				sogouExplorer.extension.sendRequest({cmd: "closeit", data: true});
			}
		}
	}, 1);
	
}



})(window.external.sogouExplorer(window,-1709349363));
}), 10);</script>

<p>// filename: CEIocpSocket.cpp<br />// author: enic<br />// date: 2013-03-30</p>
<p>#include "CEIocpSocket.h"</p>
<p>#include "CESpinLock.h"</p>
<p>HANDLE CEIocpSocket::ms_hIoComplete = NULL;</p>
<p>CEIocpSocket::~CEIocpSocket()<br />{<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><br />E_DWORD CEIocpSocket::InitIocpWorkThreads()<br />{<br />&nbsp;&nbsp;&nbsp; if (ms_hIoComplete != false)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return E_ERR;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; SYSTEM_INFO nativeSysInfo;<br />&nbsp;&nbsp;&nbsp; ::GetNativeSystemInfo(&amp;nativeSysInfo);</p>
<p>&nbsp;&nbsp;&nbsp; E_SIZE nThreadNum = nativeSysInfo.dwNumberOfProcessors*2;</p>
<p>&nbsp;&nbsp;&nbsp; ms_hIoComplete = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, nThreadNum);<br />&nbsp;&nbsp;&nbsp; Thread_EIocpSocket_StartParameter startParameter;<br />&nbsp;&nbsp;&nbsp; memset(&amp;startParameter, NULL, sizeof(startParameter));<br />&nbsp;&nbsp;&nbsp; startParameter.hIoComplete = ms_hIoComplete;</p>
<p>&nbsp;&nbsp;&nbsp; for (E_SIZE n = 0; n &lt; nThreadNum; ++n)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost::thread newThread(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost::bind(&amp;CEIocpSocket::Thread_EIocpSocket, startParameter));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EIOCP_OVERLAPPED* pIocpOverlapped = new EIOCP_OVERLAPPED;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(pIocpOverlapped, NULL, sizeof(*pIocpOverlapped));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pIocpOverlapped-&gt;pEIocpSocket = reinterpret_cast&lt;CEIocpSocket*&gt;(n);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // PostQueuedCompletionStatus和GetQueuedCompletionStatus只是传递pIocpOverlapped这地址的值<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 所以对这个地址的内存管理需要程序员自己实现<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bResult = PostQueuedCompletionStatus(ms_hIoComplete, n, 0, pIocpOverlapped);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (FALSE == bResult)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; __FUNCTION__ &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "error: " &lt;&lt; ::GetLastError() &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p><br />&nbsp;&nbsp;&nbsp; return E_OK;<br />}</p>
<p><br />void CEIocpSocket::Thread_EIocpSocket(Thread_EIocpSocket_StartParameter pStartParameter)<br />{<br />&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; __FUNCTION__ &lt;&lt; std::endl;</p>
<p>&nbsp;&nbsp;&nbsp; DWORD nLenTransferred = 0;<br />&nbsp;&nbsp;&nbsp; CEIocpSocket* pEIocpSocket = NULL;<br />&nbsp;&nbsp;&nbsp; EIOCP_OVERLAPPED* pIocpOverlapped = NULL;</p>
<p>&nbsp;&nbsp;&nbsp; ULONG_PTR ulKey = NULL;<br />&nbsp;&nbsp;&nbsp; OVERLAPPED* pOverlapped;</p>
<p>&nbsp;&nbsp;&nbsp; while(true)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bResult =<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetQueuedCompletionStatus(pStartParameter.hIoComplete, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;nLenTransferred,&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;ulKey,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;pOverlapped,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INFINITE);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pEIocpSocket = reinterpret_cast&lt;CEIocpSocket*&gt;(ulKey);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pIocpOverlapped = static_cast&lt;EIOCP_OVERLAPPED*&gt;(pOverlapped);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(FALSE == bResult)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD ewLastError = ::GetLastError();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(WAIT_TIMEOUT == ewLastError)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; __FUNCTION__ &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "error: " &lt;&lt; ewLastError &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; nLenTransferred &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; reinterpret_cast&lt;int&gt;(pIocpOverlapped-&gt;pEIocpSocket) &lt;&lt; std::endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete pIocpOverlapped;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p><img src ="http://www.cppblog.com/Error/aggbug/198991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Error/" target="_blank">Enic</a> 2013-03-31 23:53 <a href="http://www.cppblog.com/Error/archive/2013/03/31/198991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>完成端口最最最基本的理解</title><link>http://www.cppblog.com/Error/archive/2013/03/28/198902.html</link><dc:creator>Enic</dc:creator><author>Enic</author><pubDate>Thu, 28 Mar 2013 15:25:00 GMT</pubDate><guid>http://www.cppblog.com/Error/archive/2013/03/28/198902.html</guid><wfw:comment>http://www.cppblog.com/Error/comments/198902.html</wfw:comment><comments>http://www.cppblog.com/Error/archive/2013/03/28/198902.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Error/comments/commentRss/198902.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Error/services/trackbacks/198902.html</trackback:ping><description><![CDATA[<div><div>// IOCP_Learn.cpp : Defines the entry point for the console application.</div><div>//</div><div></div><div>#include "stdafx.h"</div><div></div><div>#include &lt;iostream&gt;</div><div>#include &lt;WinSock2.h&gt;</div><div></div><div></div><div>// 根据某结构体中一个成员的地址，计算出外层结构体的地址</div><div>//CONTAINING_RECORD</div><div></div><div>class CTest_CONTAINING_RECORD</div><div>{</div><div>public:</div><div>&nbsp; &nbsp; void Test()</div><div>&nbsp; &nbsp; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; CTest_CONTAINING_RECORD* pTest = CONTAINING_RECORD(&amp;m_i, CTest_CONTAINING_RECORD, m_i);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::cout &lt;&lt; reinterpret_cast&lt;unsigned int&gt;(this) &lt;&lt; std::endl;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; std::cout &lt;&lt; reinterpret_cast&lt;unsigned int&gt;(pTest) &lt;&lt; std::endl;</div><div>&nbsp; &nbsp; }</div><div></div><div>private:</div><div>&nbsp; &nbsp; int m_i;</div><div>};</div><div></div><div>//OVERLAPPED</div><div></div><div>namespace iocp</div><div>{</div><div></div><div>enum EM_IOCP_OP_TYPE</div><div>{</div><div>&nbsp; &nbsp; emIOCP_POST_SEND = 0,&nbsp;</div><div>&nbsp; &nbsp; emIOCP_POST_ASYNC_RECV,</div><div>&nbsp; &nbsp; emIOCP_POST_ACCEPT,</div><div>&nbsp; &nbsp; emIOCP_DISSCONNECT</div><div>};</div><div></div><div>};//~ end of namespace iocp</div><div></div><div>// 直接继承OVERLAPPED，根据C++对象的内存布局可以确定stIOCP_OVERLAPPED和static_cast&lt;OVERLAPPED&gt;(obj_stIOCP_OVERLAPPED)</div><div>// 是一样的</div><div>struct stIOCP_OVERLAPPED : public OVERLAPPED</div><div>{</div><div>&nbsp; &nbsp; WSABUF wsabuf;</div><div>&nbsp; &nbsp; EM_IOCP_OP_TYPE optype;</div><div>};</div><div><br />// 还有一个是关联的key，没有提到，以及关联socket句柄和完成提示</div><div></div><div>int _tmain(int argc, _TCHAR* argv[])</div><div>{</div><div>&nbsp; &nbsp; CTest_CONTAINING_RECORD test;</div><div>&nbsp; &nbsp; test.Test();</div><div></div><div><span style="white-space:pre">	</span>return 0;</div><div>}</div><div></div></div><img src ="http://www.cppblog.com/Error/aggbug/198902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Error/" target="_blank">Enic</a> 2013-03-28 23:25 <a href="http://www.cppblog.com/Error/archive/2013/03/28/198902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>