namespace Test { using System; using System.Net; using System.Net.Sockets; using System.Text; using Microshaoft; public class AsyncSocketAsyncQueueHandlerProxyServer { public static int Main(String[] args) { AsyncSocketAsyncQueueHandlerProxyServer x = new AsyncSocketAsyncQueueHandlerProxyServer(); x.StartListening(); return 0; } public void StartListening() { //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); IPAddress ipAddress; IPAddress.TryParse("127.0.0.1", out ipAddress); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 12021); Socket listener = new Socket ( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp ); listener.Bind(localEndPoint); Console.WriteLine("Listening ..."); listener.Listen(10); int i = 0; while (true) { Socket proxySocket = listener.Accept(); //socket.Blocking = true; Console.WriteLine("accept"); Socket socket = new Socket ( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp ); socket.Blocking = true; socket.Connect("bbs.newsmth.net", 23); //连接 UserToken token = new UserToken(); token.userID = "handler"; SocketAsyncDataHandler<UserToken> handler = new SocketAsyncDataHandler<UserToken>(socket, token); handler.ReceiveDataBufferLength = 1; handler.ID = 0; handler.StartReceiveData(); UserToken token2 = new UserToken(); token2.userID = "proxy"; SocketAsyncDataHandler<UserToken> proxyHandler = new SocketAsyncDataHandler<UserToken>(proxySocket, token2); proxyHandler.ReceiveDataBufferLength = 1; proxyHandler.ID = i++; proxyHandler.StartReceiveData(); ProxyHandlersPair<UserToken> pair = new ProxyHandlersPair<UserToken>(handler, proxyHandler); pair.DataReceivedProxy += new ProxyHandlersPair<UserToken>.DataReceivedProxyEventHandler(pair_DataReceivedProxy); } } void pair_DataReceivedProxy(SocketAsyncDataHandler<UserToken> source, byte[] data, SocketAsyncDataHandler<UserToken> destination) { string s = Encoding.GetEncoding("gbk").GetString(data); Console.WriteLine("[source: {0}],[destination: {1}],[data: {2}],[length: {3}]", source.Token.userID, destination.Token.userID, s, data.Length); destination.SendDataAsync(data); } } public class UserToken { public string userID; } } namespace Microshaoft { using System; using System.Net.Sockets; using System.Text; using System.Threading; public class ProxyHandlersPair<T> { private SocketAsyncDataHandler<T> _proxyHandler; public SocketAsyncDataHandler<T> ProxyHandler { get { return _proxyHandler; } } private SocketAsyncDataHandler<T> _handler; public SocketAsyncDataHandler<T> Handler { get { return _handler; } } public delegate void DataReceivedProxyEventHandler ( SocketAsyncDataHandler<T> source , byte[] data , SocketAsyncDataHandler<T> destination ); public event DataReceivedProxyEventHandler DataReceivedProxy; public ProxyHandlersPair(SocketAsyncDataHandler<T> proxy, SocketAsyncDataHandler<T> handler) { _proxyHandler = proxy; _handler = handler; _handler.DataReceivedCompletedAsync += new SocketAsyncDataHandler<T>.DataReceivedCompletedAsyncEventHandler(handler_DataReceivedCompletedAsyncProcess); _proxyHandler.DataReceivedCompletedAsync += new SocketAsyncDataHandler<T>.DataReceivedCompletedAsyncEventHandler(proxyHandler_DataReceivedCompletedAsyncProcess); } public void proxyHandler_DataReceivedCompletedAsyncProcess(SocketAsyncDataHandler<T> sender, byte[] data) { if (DataReceivedProxy != null) { DataReceivedProxy(sender, data, _handler); } } public void handler_DataReceivedCompletedAsyncProcess(SocketAsyncDataHandler<T> sender, byte[] data) { if (DataReceivedProxy != null) { DataReceivedProxy(sender, data, _proxyHandler); } } } } namespace Microshaoft { using System; using System.Net; using System.Net.Sockets; using System.Text; using System.IO; using System.Threading; public class SocketAsyncDataHandler<T> { private AsyncQueue<byte[]> _sendQueue; private AsyncQueue<byte[]> _receiveQueue; private T _token; public T Token { get { return _token; } } public SocketAsyncDataHandler(Socket socket, T token) { _sendQueue = new AsyncQueue<byte[]>(); _sendQueue.OnDequeue += new AsyncQueue<byte[]>.QueueEventHandler(SendQueue_OnDequeue); //_sendQueue.OnQueueLog += new AsyncQueue<byte[]>.QueueLogEventHandler(Queue_OnQueueLog); _sendQueue.OnException += new AsyncQueue<byte[]>.ExceptionEventHandler(Queue_OnException); _sendQueue.MaxConcurrentThreadsCount = 1; _receiveQueue = new AsyncQueue<byte[]>(); _receiveQueue.OnDequeue += new AsyncQueue<byte[]>.QueueEventHandler(ReceiveQueue_OnDequeue); //_receiveQueue.OnQueueLog += new AsyncQueue<byte[]>.QueueLogEventHandler(Queue_OnQueueLog); _receiveQueue.OnException += new AsyncQueue<byte[]>.ExceptionEventHandler(Queue_OnException); _socket = socket; _token = token; } void Queue_OnException(Exception e) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(e.Message); Console.ResetColor(); } void Queue_OnQueueLog(string logMessage) { // Console.WriteLine(logMessage); } void SendQueue_OnDequeue(byte[] element) { SendDataAsync(element); } void ReceiveQueue_OnDequeue(byte[] element) { if (DataReceivedCompletedAsync != null) { DataReceivedCompletedAsync(this, element); } } public enum ExceptionHandleAction : int { Ignore , ReThrow , Abort } private Socket _socket; private int _id; public int ID { set { _id = value; } get { return _id; } } private int _receiveDataBufferLength = 1024; public int ReceiveDataBufferLength { set { _receiveDataBufferLength = value; } } public void SendData(byte[] data) { _socket.Send(data); } public void SendDataAsyncQueue(byte[] data) { _sendQueue.Enqueue(data); } public void SendDataAsync(byte[] data) { SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.AcceptSocket = _socket; e.SetBuffer(data, 0, data.Length); _socket.SendAsync(e); } public delegate void DataReceivedCompletedAsyncEventHandler ( SocketAsyncDataHandler<T> sender , byte[] data ); public event DataReceivedCompletedAsyncEventHandler DataReceivedCompletedAsync; public delegate void ExceptionOccursEventHandler ( SocketAsyncDataHandler<T> sender , Exception exception , ExceptionHandleAction action ); public ExceptionOccursEventHandler ExceptionOccurs; public void StartReceiveData() { SocketAsyncEventArgs receive = new SocketAsyncEventArgs(); receive.AcceptSocket = _socket; receive.Completed += new EventHandler<SocketAsyncEventArgs>(ReceivedData_Completed); byte[] buffer = new byte[_receiveDataBufferLength]; receive.SetBuffer(buffer, 0, buffer.Length); _socket.ReceiveAsync(receive); } void ReceivedData_Completed(object sender, SocketAsyncEventArgs e) { int l = e.BytesTransferred; if (l > 0) { byte[] data = new byte[l]; Buffer.BlockCopy(e.Buffer, 0, data, 0, data.Length); _receiveQueue.Enqueue(data); } _socket.ReceiveAsync(e); } } } namespace Microshaoft { using System; using System.Threading; using System.Collections.Generic; public class AsyncQueue<T> where T : class { public delegate void QueueEventHandler(T element); public event QueueEventHandler OnDequeue; public delegate void QueueLogEventHandler(string logMessage); public event QueueLogEventHandler OnQueueLog; public delegate void ExceptionEventHandler(Exception exception); public event ExceptionEventHandler OnException; private Queue<T> _queue = new Queue<T>(); private static object _SyncLockObject = new object(); private int _concurrentThreadsCount = 0; //Microshaoft 用于控制并发线程数 private volatile bool _queueRuning = false; private int _maxConcurrentThreadsCount = 1; //Microshaoft 允许并发出列处理线程数为 1 public int MaxConcurrentThreadsCount { set { _maxConcurrentThreadsCount = value; } get { return _maxConcurrentThreadsCount; } } /// private long _EnqueueCount = 0; //入列计数器 /// public long EnqueueCount /// { /// get /// { /// return _EnqueueCount; /// } /// } /// private long _DequeueCount = 0; //出列计数器 /// public long DequeueCount /// { /// get /// { /// return _DequeueCount; /// } /// } //Microshaoft 服务启动后可立即开启新的线程调用此方法(死循环) private void QueueRun() //Microshaoft ThreadStart { if (!_queueRuning) { _queueRuning = true; lock (_SyncLockObject) { ThreadStart ts = new ThreadStart(QueueRunThreadProcess); Thread t = new Thread(ts); t.Name = "QueueRunThreadProcess"; t.Start(); } } } public int Count { get { return _queue.Count; } } public int ConcurrentThreadsCount { get { return _concurrentThreadsCount; } } private void QueueRunThreadProcess() { if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "Queue Runing Start ..." , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } while (_queue.Count > 0) //Microshaoft 死循环 { T element = null; int threadID = -1; lock (_SyncLockObject) { if (_concurrentThreadsCount < _maxConcurrentThreadsCount) { if (_queue.Count > 0) { Interlocked.Increment(ref _concurrentThreadsCount); threadID = _concurrentThreadsCount; if (_concurrentThreadsCount >= _maxConcurrentThreadsCount) { if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "Threads is Full!" , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } } if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "Threads ++ !" , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } element = _queue.Dequeue(); } } } if (element != null) { //Microshaoft ThreadPool.QueueUserWorkelement(new WaitCallback(OnDequeueThreadProcess), element); ThreadProcessState tps = new ThreadProcessState(); tps.element = element; tps.Sender = this; Thread t = new Thread(new ThreadStart(tps.ThreadProcess)); t.Name = string.Format("ConcurrentThread[{0}]", threadID); t.Start(); } } _queueRuning = false; if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "Queue Runing Stopped!" , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } } public void Enqueue(T element) { try { lock (_SyncLockObject) //还算并发吗? { _queue.Enqueue(element); } //Interlocked.Increment(ref _EnqueueCount); } catch (Exception e) { if (OnException != null) { OnException(e); } } if (!_queueRuning) { QueueRun(); } } private void OnDequeueThreadProcess(T element) { try { if (OnDequeue != null) { OnDequeue(element); } //Interlocked.Increment(ref _DequeueCount); DequeueProcess(); } catch (Exception e) { if (OnException != null) { OnException(e); } } finally { Interlocked.Decrement(ref _concurrentThreadsCount); if (_concurrentThreadsCount == 0) { if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "All Threads Finished!" , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } } if (OnQueueLog != null) { OnQueueLog ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}" , "Threads -- !" , _concurrentThreadsCount , _queue.Count , Thread.CurrentThread.Name ) ); } } } private void DequeueProcess() { while (_queue.Count > 0) { T element = null; lock (_SyncLockObject) { if (_queue.Count > 0) { element = _queue.Dequeue(); } } if (element != null) { if (OnDequeue != null) { OnDequeue(element); } //Interlocked.Increment(ref _DequeueCount); } } } private class ThreadProcessState { private AsyncQueue<T> _sender; public AsyncQueue<T> Sender { get { return _sender; } set { _sender = value; } } private T _element; public T element { get { return _element; } set { _element = value; } } public void ThreadProcess() { _sender.OnDequeueThreadProcess(_element); } } } }