經典程式碼IOCP(完成埠)的C#.Net實現----解讀
感謝原作者
重複造輪子的意義在於深刻的理解和學習---
main.cs:
/*using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace c2iocp { class Program { static void Main(string[] args) { } } } */ using System; using System.Threading; // Included for the Thread.Sleep call using Continuum.Threading; namespace Sample { //============================================ /// <summary> Sample class for the threading class </summary> public class UtilThreadingSample { //******************************************* /// <summary> Test Method </summary> static void Main() { // Create the MSSQL IOCP Thread Pool IOCPThreadPool pThreadPool = new IOCPThreadPool(0, 5, 10, new IOCPThreadPool.USER_FUNCTION(IOCPThreadFunction)); pThreadPool.PostEvent(10); Thread.Sleep(10000); pThreadPool.Dispose(); } //***************************************** /// <summary> Function to be called by the IOCP thread pool. Called when /// a command is posted for processing by the SocketManager </summary> /// <param name="iValue"> The value provided by the thread posting the event </param> static public void IOCPThreadFunction(Int32 iValue) { try { Console.WriteLine("Value: {0}", iValue); } catch (Exception pException) { Console.WriteLine(pException.Message); } } } }
continuum.cs
using System; using System.Threading; using System.Runtime.InteropServices; namespace Continuum.Threading { // Structures //========================================== /// <summary> This is the WIN32 OVERLAPPED structure </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public unsafe struct OVERLAPPED { UInt32* ulpInternal; UInt32* ulpInternalHigh; Int32 lOffset; Int32 lOffsetHigh; UInt32 hEvent; } // Classes //============================================ /// <summary> This class provides the ability to create a thread pool to manage work. The /// class abstracts the Win32 IOCompletionPort API so it requires the use of /// unmanaged code. Unfortunately the .NET framework does not provide this functionality </summary> public sealed class IOCPThreadPool { // Win32 Function Prototypes /// <summary> Win32Func: Create an IO Completion Port Thread Pool </summary> [DllImport("Kernel32", CharSet = CharSet.Auto)] private unsafe static extern UInt32 CreateIoCompletionPort(UInt32 hFile, UInt32 hExistingCompletionPort, UInt32* puiCompletionKey, UInt32 uiNumberOfConcurrentThreads); /// <summary> Win32Func: Closes an IO Completion Port Thread Pool </summary> [DllImport("Kernel32", CharSet = CharSet.Auto)] private unsafe static extern Boolean CloseHandle(UInt32 hObject); /// <summary> Win32Func: Posts a context based event into an IO Completion Port Thread Pool </summary> [DllImport("Kernel32", CharSet = CharSet.Auto)] private unsafe static extern Boolean PostQueuedCompletionStatus(UInt32 hCompletionPort, UInt32 uiSizeOfArgument, UInt32* puiUserArg, OVERLAPPED* pOverlapped); /// <summary> Win32Func: Waits on a context based event from an IO Completion Port Thread Pool. /// All threads in the pool wait in this Win32 Function </summary> [DllImport("Kernel32", CharSet = CharSet.Auto)] private unsafe static extern Boolean GetQueuedCompletionStatus(UInt32 hCompletionPort, UInt32* pSizeOfArgument, UInt32* puiUserArg, OVERLAPPED** ppOverlapped, UInt32 uiMilliseconds); // Constants /// <summary> SimTypeConst: This represents the Win32 Invalid Handle Value Macro </summary> private const UInt32 INVALID_HANDLE_VALUE = 0xffffffff; /// <summary> SimTypeConst: This represents the Win32 INFINITE Macro </summary> private const UInt32 INIFINITE = 0xffffffff; /// <summary> SimTypeConst: This tells the IOCP Function to shutdown </summary> private const Int32 SHUTDOWN_IOCPTHREAD = 0x7fffffff; // Delegate Function Types /// <summary> DelType: This is the type of user function to be supplied for the thread pool </summary> public delegate void USER_FUNCTION(Int32 iValue); // Private Properties private UInt32 m_hHandle; /// <summary> SimType: Contains the IO Completion Port Thread Pool handle for this instance </summary> private UInt32 GetHandle { get { return m_hHandle; } set { m_hHandle = value; } } private Int32 m_uiMaxConcurrency; /// <summary> SimType: The maximum number of threads that may be running at the same time </summary> private Int32 GetMaxConcurrency { get { return m_uiMaxConcurrency; } set { m_uiMaxConcurrency = value; } } private Int32 m_iMinThreadsInPool; /// <summary> SimType: The minimal number of threads the thread pool maintains </summary> private Int32 GetMinThreadsInPool { get { return m_iMinThreadsInPool; } set { m_iMinThreadsInPool = value; } } private Int32 m_iMaxThreadsInPool; /// <summary> SimType: The maximum number of threads the thread pool maintains </summary> private Int32 GetMaxThreadsInPool { get { return m_iMaxThreadsInPool; } set { m_iMaxThreadsInPool = value; } } private Object m_pCriticalSection; /// <summary> RefType: A serialization object to protect the class state </summary> private Object GetCriticalSection { get { return m_pCriticalSection; } set { m_pCriticalSection = value; } } private USER_FUNCTION m_pfnUserFunction; /// <summary> DelType: A reference to a user specified function to be call by the thread pool </summary> private USER_FUNCTION GetUserFunction { get { return m_pfnUserFunction; } set { m_pfnUserFunction = value; } } private Boolean m_bDisposeFlag; /// <summary> SimType: Flag to indicate if the class is disposing </summary> private Boolean IsDisposed { get { return m_bDisposeFlag; } set { m_bDisposeFlag = value; } } // Public Properties private Int32 m_iCurThreadsInPool; /// <summary> SimType: The current number of threads in the thread pool </summary> public Int32 GetCurThreadsInPool { get { return m_iCurThreadsInPool; } set { m_iCurThreadsInPool = value; } } /// <summary> SimType: Increment current number of threads in the thread pool </summary> private Int32 IncCurThreadsInPool() { return Interlocked.Increment(ref m_iCurThreadsInPool); } /// <summary> SimType: Decrement current number of threads in the thread pool </summary> private Int32 DecCurThreadsInPool() { return Interlocked.Decrement(ref m_iCurThreadsInPool); } private Int32 m_iActThreadsInPool; /// <summary> SimType: The current number of active threads in the thread pool </summary> public Int32 GetActThreadsInPool { get { return m_iActThreadsInPool; } set { m_iActThreadsInPool = value; } } /// <summary> SimType: Increment current number of active threads in the thread pool </summary> private Int32 IncActThreadsInPool() { return Interlocked.Increment(ref m_iActThreadsInPool); } /// <summary> SimType: Decrement current number of active threads in the thread pool </summary> private Int32 DecActThreadsInPool() { return Interlocked.Decrement(ref m_iActThreadsInPool); } private Int32 m_iCurWorkInPool; /// <summary> SimType: The current number of Work posted in the thread pool </summary> public Int32 GetCurWorkInPool { get { return m_iCurWorkInPool; } set { m_iCurWorkInPool = value; } } /// <summary> SimType: Increment current number of Work posted in the thread pool </summary> private Int32 IncCurWorkInPool() { return Interlocked.Increment(ref m_iCurWorkInPool); } /// <summary> SimType: Decrement current number of Work posted in the thread pool </summary> private Int32 DecCurWorkInPool() { return Interlocked.Decrement(ref m_iCurWorkInPool); } // Constructor, Finalize, and Dispose //*********************************************** /// <summary> Constructor </summary> /// <param name = "iMaxConcurrency"> SimType: Max number of running threads allowed </param> /// <param name = "iMinThreadsInPool"> SimType: Min number of threads in the pool </param> /// <param name = "iMaxThreadsInPool"> SimType: Max number of threads in the pool </param> /// <param name = "pfnUserFunction"> DelType: Reference to a function to call to perform work </param> /// <exception cref = "Exception"> Unhandled Exception </exception> public IOCPThreadPool(Int32 iMaxConcurrency, Int32 iMinThreadsInPool, Int32 iMaxThreadsInPool, USER_FUNCTION pfnUserFunction) { try { // Set initial class state GetMaxConcurrency = iMaxConcurrency;//系統允許的最大執行緒數,如果為0,則和核心數一致,一般都是0, GetMinThreadsInPool = iMinThreadsInPool;//最小執行緒數目 GetMaxThreadsInPool = iMaxThreadsInPool;//最大執行緒數目,都是設定給的引數 GetUserFunction = pfnUserFunction;//傳遞過來的回撥函式,或者說事件處理函式 // Init the thread counters GetCurThreadsInPool = 0;//當前執行緒池裡的執行緒數 GetActThreadsInPool = 0;//活動的執行緒數,正在工作的執行緒數 GetCurWorkInPool = 0;//被投遞的事件數目 // Initialize the Monitor Object GetCriticalSection = new Object();//來包含類狀態的物件???? // Set the disposing flag to false IsDisposed = false;//是否資源釋放標誌 unsafe//c#呼叫外面dll的時候,需要用這個unsafe { // Create an IO Completion Port for Thread Pool use //步驟1:建立iocp埠, /* * 引數說明編輯 FileHandle是有效的檔案控制代碼或INVALID_HANDLE_VALUE。 ExistingCompletionPort是已經存在的完成埠。如果為NULL,則為新建一個IOCP。 CompletionKey是傳送給處理函式的引數。 NumberOfConcurrentThreads是有多少個執行緒在訪問這個訊息佇列。當引數ExistingCompletionPort不為0的時候,系統忽略該引數,當該引數為0表示允許同時相等數目於處理器個數的執行緒訪問該訊息佇列。 返回值編輯 返回一個IOCP的控制代碼。若為NULL則建立失敗,不為NULL則建立成功。 * * CreateIoCompletionPort的前三個引數只在把裝置同Complete Port相關聯時才有用。 此時我們只需傳遞INVALID_HANDLE_VALUE,NULL和0即可。 第四個引數告訴埠同時能執行的最多執行緒數,這裡設定為0,表示預設為當前計算機的CPU數目。 */ GetHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, null, (UInt32)GetMaxConcurrency); } // Test to make sure the IO Completion Port was created if (GetHandle == 0) throw new Exception("Unable To Create IO Completion Port"); // Allocate and start the Minimum number of threads specified Int32 iStartingCount = GetCurThreadsInPool;//當前執行緒池裡的執行緒數目 ThreadStart tsThread = new ThreadStart(IOCPFunction);//// 摘要: 表示在 System.Threading.Thread 上執行的方法。public delegate void ThreadStart(); /* * 2 我們的ThreadFun執行緒函式執行一些初始化之後,將進入一個迴圈,該迴圈會在服務程序終止時才結束。 在迴圈中,呼叫GetQueuedCompletionStatus,這樣就把當前執行緒的ID放入一個等待執行緒佇列中,I/O CP核心物件就總能知道哪個執行緒在等待處理完成的I/O請求。 如果在IDLE_THREAD_TIMEOUT規定的時間內I/O CP上還沒有出現一個Completion Packet,則轉入下一次迴圈。在這裡我們設定的IDLE_THREAD_TIMEOUT為1秒。 當埠的I/O完成佇列中出現一項時,完成埠就喚醒等待執行緒佇列中的這個執行緒,該執行緒將得到完成的I/O項中的資訊: 傳輸的位元組數、完成鍵和OVERLAPPED結構的地址。 在我們的程式中可以用智慧指標或者BSTR或者int來接受這個OVERLAPPED結構的地址的值,從而得到訊息;然後在這個執行緒中處理訊息。 GetQueuedCompletionStatus的第一個引數hCompletionPort指出了要監視哪一個埠,這裡我們傳送先前從CreateIoCompletionPort返回的埠控制代碼。 */ for (Int32 iThread = 0; iThread < GetMinThreadsInPool; ++iThread) { // Create a thread and start it Thread thThread = new Thread(tsThread); thThread.Name = "IOCP " + thThread.GetHashCode(); thThread.Start(); // Increment the thread pool count IncCurThreadsInPool();//原子操作+1初始為0 /* * long m_dwRefCount.. InterlockedIncrement(&m_dwRefCount) 對m_dwRefCount加1 在對m_dwRefCount訪問的時候其他執行緒不能訪問這個變數 InterlockedIncrement實現的是原子性的加減,什麼是原子性的加減呢? 舉例:如果一個變數long value = 0; 首先說一下正常情況下的加減操作,value+=1; 1.系統從value的空間取出值,並動態生成一個空間儲存取出來的值; 2.將取出來的值和1做加法,並將和放入value的空間覆蓋掉原值,操作結束; 如果此時有2個Thread,分別記作AThread,BThread 1.AThread將value從儲存空間取出,為0; 2.BThread將value從儲存空間取出,為0; 3.AThread將取出來的值和1做加法,並將和放入value的空間覆蓋掉原值,加法結束,value = 1; 4.BThread將取出來的值和1做加法,並將和放入value的空間覆蓋掉原值,加法結束,value = 1; 最後value應該是2,InterlockedIncrement保證一個執行緒訪問變數時其他執行緒不能訪問。 用於增減變數的並不是常用的Inc/Dec過程,而是用了InterlockedIncrement/InterlockedDecrement這一對過程,它們實現的功能完全一樣,都是對變數加一或減一。 但它們有一個最大的區別,那就是InterlockedIncrement/InterlockedDecrement是執行緒安全的。 即它們在多執行緒下能保證執行結果正確,而Inc/Dec不能。 或者按作業系統理論中的術語來說,這是一對“原語”操作。 */ } } catch { throw new Exception("Unhandled Exception"); } } //*********************************************** /// <summary> Finalize called by the GC </summary> ~IOCPThreadPool() { /* * 這個類結束,應該也意味著是主執行緒了,所以只有主執行緒訪問?,既然是主執行緒,為什麼還要加標誌位呢???? */ if (!IsDisposed)//還沒有釋放資源,則釋放,這個應該也是原子操作對isdisposeD吧 Dispose(); } //********************************************** /// <summary> Called when the object will be shutdown. This /// function will wait for all of the work to be completed /// inside the queue before completing </summary> public void Dispose() { try { // Flag that we are disposing this object IsDisposed = true; // Get the current number of threads in the pool Int32 iCurThreadsInPool = GetCurThreadsInPool;//現在生成的執行緒數,用原子操作實現的 // Shutdown all thread in the pool for (Int32 iThread = 0; iThread < iCurThreadsInPool; ++iThread) { unsafe { bool bret = PostQueuedCompletionStatus(GetHandle, 4, (UInt32*)SHUTDOWN_IOCPTHREAD, null); /* * PostQueuedCompletionStatus函式,向每個工作者執行緒都發送—個特殊的完成資料包。該函式會指示每個執行緒都“立即結束並退出”. * 下面是PostQueuedCompletionStatus函式的定義: [cpp] view plain copy BOOL PostQueuedCompletionStatus( HANDLE CompletlonPort, DW0RD dwNumberOfBytesTrlansferred, DWORD dwCompletlonKey, LPOVERLAPPED lpoverlapped, ); 其中,CompletionPort引數指定想向其傳送一個完成資料包的完成埠物件。而就dwNumberOfBytesTransferred,dwCompletionKey和lpOverlapped * 這三個引數來說.每—個都允許我們指定—個值,直接傳遞給GetQueuedCompletionStatus函式中對應的引數。這樣—來。 * —個工作者執行緒收到傳遞過來的三個GetQueuedCompletionStatus函式引數後,便可根據由這三個引數的某一個設定的特殊值, * 決定何時應該退出。例如,可用dwCompletionPort引數傳遞0值,而—個工作者執行緒會將其解釋成中止指令。一旦所有工作者執行緒都已關閉, * 便可使用CloseHandle函式,關閉完成埠。最終安全退出程式。 PostQueuedCompletionStatus函式提供了一種方式來與執行緒池中的所有執行緒進行通訊。如,當用戶終止服務應用程式時,我們想要所有執行緒都完全利索地退出。 * 但是如果各執行緒還在等待完成埠而又沒有已完成的I/O 請求,那麼它們將無法被喚醒。 通過為執行緒池中的每個執行緒都呼叫一次PostQueuedCompletionStatus,我們可以將它們都喚醒。每個執行緒會對GetQueuedCompletionStatus的返回值進行檢查, * 如果發現應用程式正在終止,那麼它們就可以進行清理工作並正常地退出。 */ } } // Wait here until all the threads are gone while (GetCurThreadsInPool != 0) Thread.Sleep(100); unsafe { // Close the IOCP Handle CloseHandle(GetHandle);//便可使用CloseHandle函式,關閉完成埠。最終安全退出程式。 } } catch { } } // Private Methods //******************************************* /// <summary> IOCP Worker Function that calls the specified user function </summary> private void IOCPFunction() { UInt32 uiNumberOfBytes; Int32 iValue; try { while (true) { unsafe { OVERLAPPED* pOv; // Wait for an event /* * BOOL GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOfBytes, PULONG_PTR lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds); 呼叫引數: CompletionPort:指定的IOCP,該值由CreateIoCompletionPort函式建立。 lpnumberofbytes:一次完成後的I/O操作所傳送資料的位元組數。 lpcompletionkey:當檔案I/O操作完成後,用於存放與之關聯的CK。 lpoverlapped:為呼叫IOCP機制所引用的OVERLAPPED結構。 dwmilliseconds:用於指定呼叫者等待CP的時間。 返回值: 呼叫成功,則返回非零數值,相關資料存於lpNumberOfBytes、lpCompletionKey、lpoverlapped變數中。失敗則返回零值。 */ GetQueuedCompletionStatus(GetHandle, &uiNumberOfBytes, (UInt32*)&iValue, &pOv, INIFINITE); } // Decrement the number of events in queue DecCurWorkInPool();//原子操作,減少一個io裡面的任務數目 // Was this thread told to shutdown if (iValue == SHUTDOWN_IOCPTHREAD)//關閉標誌位,post傳遞一個io完成資料,這裡讀到,知道該結束了,提前約定 break; // Increment the number of active threads IncActThreadsInPool();//這個執行緒讀到任務開始工作,增加活動執行緒數 try { // Call the user function GetUserFunction(iValue); } catch { } // Get a lock Monitor.Enter(GetCriticalSection); try { // If we have less than max threads currently in the pool //當前已經生成了符合設定最小執行緒數目的執行緒,如果當前每到最大執行緒數,繼續建立 if (GetCurThreadsInPool < GetMaxThreadsInPool) { // Should we add a new thread to the pool //所有執行緒都已在工作 if (GetActThreadsInPool == GetCurThreadsInPool) { if (IsDisposed == false)//沒有進行資源釋放,標誌位的作用在這裡 { // Create a thread and start it ThreadStart tsThread = new ThreadStart(IOCPFunction); Thread thThread = new Thread(tsThread); thThread.Name = "IOCP " + thThread.GetHashCode(); thThread.Start(); // Increment the thread pool count IncCurThreadsInPool();//增加當前的活動總數,子執行緒還可以繼續生成執行緒???? } } } } catch { } // Relase the lock Monitor.Exit(GetCriticalSection);//這個是為了保證,比如當前程序為5都在工作了,最大上限設定10, //發現都在工作只增加1個額外空閒執行緒,如果不用 Monitor 是不是會都發現不夠一下增加太多,最後可能當前執行緒數超過10 // Increment the number of active threads DecActThreadsInPool();//幹活結束,減少忙碌狀態的執行緒 } } catch { } // Decrement the thread pool count DecCurThreadsInPool();//執行緒退出,減少當前程序數 } // Public Methods //****************************************** /// <summary> IOCP Worker Function that calls the specified user function </summary> /// <param name="iValue"> SimType: A value to be passed with the event </param> /// <exception cref = "Exception"> Unhandled Exception </exception> public void PostEvent(Int32 iValue) { try { // Only add work if we are not disposing if (IsDisposed == false) { unsafe { // Post an event into the IOCP Thread Pool PostQueuedCompletionStatus(GetHandle, 4, (UInt32*)iValue, null); } // Increment the number of item of work IncCurWorkInPool(); // Get a lock Monitor.Enter(GetCriticalSection); try { // If we have less than max threads currently in the pool if (GetCurThreadsInPool < GetMaxThreadsInPool) { // Should we add a new thread to the pool if (GetActThreadsInPool == GetCurThreadsInPool) { if (IsDisposed == false) { // Create a thread and start it ThreadStart tsThread = new ThreadStart(IOCPFunction); Thread thThread = new Thread(tsThread); thThread.Name = "IOCP " + thThread.GetHashCode(); thThread.Start(); // Increment the thread pool count IncCurThreadsInPool(); } } } } catch { } // Release the lock Monitor.Exit(GetCriticalSection); } } catch (Exception e) { throw e; } catch { throw new Exception("Unhandled Exception"); } } //***************************************** /// <summary> IOCP Worker Function that calls the specified user function </summary> /// <exception cref = "Exception"> Unhandled Exception </exception> public void PostEvent() { try { // Only add work if we are not disposing if (IsDisposed == false) { unsafe { // Post an event into the IOCP Thread Pool PostQueuedCompletionStatus(GetHandle, 0, null, null); } // Increment the number of item of work IncCurWorkInPool(); // Get a lock Monitor.Enter(GetCriticalSection); try { // If we have less than max threads currently in the pool if (GetCurThreadsInPool < GetMaxThreadsInPool) { // Should we add a new thread to the pool if (GetActThreadsInPool == GetCurThreadsInPool) { if (IsDisposed == false) { // Create a thread and start it ThreadStart tsThread = new ThreadStart(IOCPFunction); Thread thThread = new Thread(tsThread); thThread.Name = "IOCP " + thThread.GetHashCode(); thThread.Start(); // Increment the thread pool count IncCurThreadsInPool(); } } } } catch { } // Release the lock Monitor.Exit(GetCriticalSection); } } catch (Exception e) { throw e; } catch { throw new Exception("Unhandled Exception"); } } } }
相關推薦
經典程式碼IOCP(完成埠)的C#.Net實現----解讀
感謝原作者 重複造輪子的意義在於深刻的理解和學習--- main.cs: /*using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace
C#高效能大容量SOCKET併發(一):IOCP完成埠例子介紹
例子主要包括SocketAsyncEventArgs通訊封裝、服務端實現日誌檢視、SCOKET列表、上傳、下載、遠端檔案流、吞吐量協議,用於測試SocketAsyncEventArgs的效能和壓力,最大連線數支援65535個長連線,最高命令互動速度達到250MB/S(使用的
No.24 我與程式碼的日常:C語言實現簡易通訊錄
#define SIZE 1000 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> typedef struct PersonInfo{ char name[102
使用c#.net實現打地鼠遊戲和翻牌遊戲
***本程式通過vs2010建立窗體應用程式,通過控制元件建立記憶紙牌及打地鼠遊戲視窗 需求分析: 為了使用者給使用者提供美觀的遊戲介面,本專案在遊戲的開發實踐中注重對介面的美觀設計,並配有背景音樂,在打地鼠遊戲中將指標變為錘子,滿足玩家打地鼠的需求。 遊戲介面圖如下***
windows IOCP完成埠原理詳解
開篇之前先放上本次講的IOCP project github地址:這裡 。這個project中包含了IOCP和select,各自封裝成一個動態連結庫,可以直接使用。同時專案配有完整的glog支援,方便除錯,並可以通過config控制server。如有bug,歡迎大家提出,
使用C#.NET 實現高效能IPX/SPX SOCKET伺服器 附原始碼
要實現 IPX/SPX 必須自己寫IPX地址類 它派生於 EndPoint. 因為.NET沒有提供此類所以必須自己寫 public class IPXEndPoint : EndPoint { byte[] NetNum;
IOCP完成埠與長連線通訊
最近在寫一個通訊代理程式的時候使用了IOCP通訊模型,幾年前也使用過IOCP,不過當時的程式是基於短連線的,而這次是長連線的,寫這個程式的過程中我覺得主要有以下幾點值得注意: 1、整個程式的架構:程式由一個Accept執行緒,n個工作者執行緒,1個執行緒池管理
C# .net實現傳送手機簡訊功能
.net實現傳送手機簡訊功能其實很簡單,只需要呼叫簡訊服務商的介面即可。程式碼如下: string url = "{0}?act=send&username={1}&passwd={2}&destnumbers={3}&
IOCP完成埠資料整理——"高大上",夠全,夠詳細
最經典: 一個簡單的IOCP(IO完成埠)伺服器/客戶端類 可伸縮的IO完成埠伺服器模型(IOCP) Build your own cryptographically safeserver/client protocol IOCP程式設計小結
採用完成埠(IOCP)實現高效能網路伺服器(Windows c++版)
前言 TCP\IP已成為業界通訊標準。現在越來越多的程式需要聯網。網路系統分為服務端和客戶端,也就是c\s模式(client \ server)。client一般有一個或少數幾個連線;server則需要處理大量連線。大部分情況下,只有服務端才特別考慮效能問題。本文主要介紹服務端處理方法,當然也可以用於客戶端
C#的一段經典程式碼,查詢當前程式所有繼承或實現自指定類的子類。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace FWJB_S
java 7之AIO對完成埠(IOCP)的實現
鑑於網上關於java7之AIO(只能在windows 作業系統下才能實現功能)實現的例項少而且講述的不夠詳細,特此寫這篇部落格供大家借鑑,希望能幫助和我一樣苦逼的java程式設計師們,也希望高手能指出部落格描述不當之處 廢話少說,直接進入主題:先貼段伺服器程式碼,程式碼沒進
C#/.NET Unity靜態實現AOP功能——實際案例Demo程式碼
C# Unity依賴注入利用Attribute實現AOP功能 在做專案時,常常要對某個功能進行擴充套件,我們一般都是利用OOP的思想, 在原有的功能上進行擴充套件。 如果能用AOP思想去擴充套件,會使程式碼的整體框架更加穩定,我推薦Unity框架,接下來介紹一下如何使用。 1
經典遊戲---貪吃蛇從C++程式碼實現
1. 題目描述 小時候都玩過貪吃蛇這個經典的小遊戲,在我們的普通手機裡似乎都是必備的。它伴隨著我們的童年,經歷了好多好多時光。它帶給我們了許多的樂趣。 學習了c++這門程式語言後,我就想著能不能把它做出來,在我查看了相關知識後,明白了其中的道理,就嘗試著自己寫出這個小遊
在c#多執行緒使用IOCP(完成埠)的簡單示例
在c#使用IOCP(完成埠)的簡單示例 上次給大家發了利用winsock原生的api來做一個同步的socket伺服器的例子,大致上只是貼了一些程式碼,相信大家這麼冰雪聰明,已經研究的差不多了。因為winsock的api使用在msdn或者google上都能很方便的查到,所以我
C#高效能網路伺服器完成埠的實現
C#中利用“完成埠”可實現socket程式設計的非同步通訊以及大容量併發等問題。廢話少說,直接上程式碼。MSDN中已有現成的例子,但是其中有一個類未給出。這裡全都有了。 1,主程式using System; using System.Collections.Generic;
C# asp.net實現文件上傳
function asp.net visual 開發 null 前端代碼: 使用visual studio開發實現文件上傳 前端頁面代碼: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.as
Json.net實現方便的Json轉C#(dynamic動態類型)對象
bar 方便 api lba c# oid tool 可能 情況 以前需要將一段json字符串轉換為C#對象時,一般都是定義一個與之對應的實體類來接收。這樣做有一個很大的缺點,就是當字符串特別長,屬性特別多,又有嵌套時,手敲這個實體類就非常痛苦。 比如之前做的一個接收百度七
C#.NET 程序員的福利,自己寫的一個XML操作類,可實現像jquery一樣方便的xml操作,且不用專門去處理命名空間。
console region ignorecas node 處理 命名空間 void clone 一個 此工具是進入一家新公司之後實現的,主要是工作當中操作 xml 的時間太多,因為公司按任務計“工作量”,領導給我安排的時間遠遠不夠完善此工具【悲哀的
(轉)ASP.NET(C#)FileUpload實現上傳限定類型和大小的文件到服務器
web 環境 posted using 結果 ring event run ont 上傳文件有兩個主要的目的地,一個是服務器,另一個是數據庫,ASP.NET內置了FileUpload這個上傳控件,文本框顯示用戶選擇的文件的全名. 其屬性主要包括: ContenLength: