//=========================================================================================== // Share.cs // csc.exe /t:library Share.cs //#define c4 //C# 4.0+ #define c4 namespace Microshaoft { using System; using System.Threading; using System.Diagnostics; using System.Collections.Generic; #if c4 using System.Collections.Concurrent; #endif using Microshaoft; public class ConcurrentAsyncQueue<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 event QueueLogEventHandler OnQueueRunningThreadStart; public event QueueLogEventHandler OnQueueRunningThreadEnd; public event QueueLogEventHandler OnDequeueThreadStart; public event QueueLogEventHandler OnDequeueThreadEnd; public event QueueLogEventHandler OnDequeueAllThreadsEnd; public delegate void ExceptionEventHandler(Exception exception); public event ExceptionEventHandler OnException; #if c2 private Queue<T> _queue = new Queue<T>(); #elif c4 private ConcurrentQueue<T> _queue = new ConcurrentQueue<T>(); #endif private object _syncQueueLockObject = new object(); //private object _syncQueueRunningLockObject = new object(); private long _isQueueRunning = 0; private long _concurrentDequeueThreadsCount = 0; //Microshaoft 用于控制并发线程数 private PerformanceCounter _enqueuePerformanceCounter; private PerformanceCounter _dequeuePerformanceCounter; private PerformanceCounter _dequeueProcessedPerformanceCounter; private PerformanceCounter _queueLengthPerformanceCounter; private PerformanceCounter _dequeueThreadStartPerformanceCounter; private PerformanceCounter _dequeueThreadEndPerformanceCounter; private PerformanceCounter _dequeueThreadsCountPerformanceCounter; private PerformanceCounter _queueRunningThreadStartPerformanceCounter; private PerformanceCounter _queueRunningThreadEndPerformanceCounter; private PerformanceCounter _queueRunningThreadsCountPerformanceCounter; private bool _isAttachedPerformanceCounters = false; public void AttachPerformanceCounters(string instanceNamePrefix) { string category = "Microshaoft AsyncConurrentQueue Counters"; string counter = string.Empty; Process process = Process.GetCurrentProcess(); //int processID = 0;//process.Id; string processName = process.ProcessName; //string processStartTime = "";//process.StartTime; string instanceName = string.Empty; instanceName = string.Format ( "{0}-{1}" , instanceNamePrefix , processName //, processID //, processStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff") ); CounterCreationDataCollection ccdc = new CounterCreationDataCollection(); if (PerformanceCounterCategory.Exists(category)) { PerformanceCounterCategory.Delete(category); } CounterCreationData ccd = null; counter = "EnqueueCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "DequeueCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "QueueLengthCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "DequeueProcessedCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "DequeueThreadStartCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "DequeueThreadEndCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "DequeueThreadsCountCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "QueueRunningThreadStartCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "QueueRunningThreadEndCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); counter = "QueueRunningThreadsCountCounter"; ccd = PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64); ccdc.Add(PerformanceCounterHelper.GetCounterCreationData(counter, PerformanceCounterType.NumberOfItems64)); PerformanceCounterCategory.Create ( category, string.Format("{0} Category Help.", category), PerformanceCounterCategoryType.MultiInstance, ccdc ); counter = "EnqueueCounter"; _enqueuePerformanceCounter = new PerformanceCounter(); _enqueuePerformanceCounter.CategoryName = category; _enqueuePerformanceCounter.CounterName = counter; _enqueuePerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _enqueuePerformanceCounter.InstanceName = instanceName; _enqueuePerformanceCounter.ReadOnly = false; _enqueuePerformanceCounter.RawValue = 0; counter = "DequeueCounter"; _dequeuePerformanceCounter = new PerformanceCounter(); _dequeuePerformanceCounter.CategoryName = category; _dequeuePerformanceCounter.CounterName = counter; _dequeuePerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _dequeuePerformanceCounter.InstanceName = instanceName; _dequeuePerformanceCounter.ReadOnly = false; _dequeuePerformanceCounter.RawValue = 0; counter = "DequeueProcessedCounter"; _dequeueProcessedPerformanceCounter = new PerformanceCounter(); _dequeueProcessedPerformanceCounter.CategoryName = category; _dequeueProcessedPerformanceCounter.CounterName = counter; _dequeueProcessedPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _dequeueProcessedPerformanceCounter.InstanceName = instanceName; _dequeueProcessedPerformanceCounter.ReadOnly = false; _dequeueProcessedPerformanceCounter.RawValue = 0; counter = "QueueLengthCounter"; _queueLengthPerformanceCounter = new PerformanceCounter(); _queueLengthPerformanceCounter.CategoryName = category; _queueLengthPerformanceCounter.CounterName = counter; _queueLengthPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _queueLengthPerformanceCounter.InstanceName = instanceName; _queueLengthPerformanceCounter.ReadOnly = false; _queueLengthPerformanceCounter.RawValue = 0; counter = "DequeueThreadStartCounter"; _dequeueThreadStartPerformanceCounter = new PerformanceCounter(); _dequeueThreadStartPerformanceCounter.CategoryName = category; _dequeueThreadStartPerformanceCounter.CounterName = counter; _dequeueThreadStartPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _dequeueThreadStartPerformanceCounter.InstanceName = instanceName; _dequeueThreadStartPerformanceCounter.ReadOnly = false; _dequeueThreadStartPerformanceCounter.RawValue = 0; counter = "DequeueThreadEndCounter"; _dequeueThreadEndPerformanceCounter = new PerformanceCounter(); _dequeueThreadEndPerformanceCounter.CategoryName = category; _dequeueThreadEndPerformanceCounter.CounterName = counter; _dequeueThreadEndPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _dequeueThreadEndPerformanceCounter.InstanceName = instanceName; _dequeueThreadEndPerformanceCounter.ReadOnly = false; _dequeueThreadEndPerformanceCounter.RawValue = 0; counter = "DequeueThreadsCountCounter"; _dequeueThreadsCountPerformanceCounter = new PerformanceCounter(); _dequeueThreadsCountPerformanceCounter.CategoryName = category; _dequeueThreadsCountPerformanceCounter.CounterName = counter; _dequeueThreadsCountPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _dequeueThreadsCountPerformanceCounter.InstanceName = instanceName; _dequeueThreadsCountPerformanceCounter.ReadOnly = false; _dequeueThreadsCountPerformanceCounter.RawValue = 0; counter = "QueueRunningThreadStartCounter"; _queueRunningThreadStartPerformanceCounter = new PerformanceCounter(); _queueRunningThreadStartPerformanceCounter.CategoryName = category; _queueRunningThreadStartPerformanceCounter.CounterName = counter; _queueRunningThreadStartPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _queueRunningThreadStartPerformanceCounter.InstanceName = instanceName; _queueRunningThreadStartPerformanceCounter.ReadOnly = false; _queueRunningThreadStartPerformanceCounter.RawValue = 0; counter = "QueueRunningThreadEndCounter"; _queueRunningThreadEndPerformanceCounter = new PerformanceCounter(); _queueRunningThreadEndPerformanceCounter.CategoryName = category; _queueRunningThreadEndPerformanceCounter.CounterName = counter; _queueRunningThreadEndPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _queueRunningThreadEndPerformanceCounter.InstanceName = instanceName; _queueRunningThreadEndPerformanceCounter.ReadOnly = false; _queueRunningThreadEndPerformanceCounter.RawValue = 0; counter = "QueueRunningThreadsCountCounter"; _queueRunningThreadsCountPerformanceCounter = new PerformanceCounter(); _queueRunningThreadsCountPerformanceCounter.CategoryName = category; _queueRunningThreadsCountPerformanceCounter.CounterName = counter; _queueRunningThreadsCountPerformanceCounter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; _queueRunningThreadsCountPerformanceCounter.InstanceName = instanceName; _queueRunningThreadsCountPerformanceCounter.ReadOnly = false; _queueRunningThreadsCountPerformanceCounter.RawValue = 0; _isAttachedPerformanceCounters = true; } private int _maxConcurrentDequeueThreadsCount = 1; //Microshaoft 允许并发出列处理线程数为 1 public int MaxConcurrentDequeueThreadsCount { set { _maxConcurrentDequeueThreadsCount = value; } get { return _maxConcurrentDequeueThreadsCount; } } //Microshaoft 服务启动后可立即开启新的线程调用此方法(死循环) private void QueueRun() //Microshaoft ThreadStart { if (Interlocked.Read(ref _concurrentDequeueThreadsCount) < _maxConcurrentDequeueThreadsCount) { if (Interlocked.CompareExchange(ref _isQueueRunning, 0, 1) == 0) { ThreadStart ts = new ThreadStart(QueueRunThreadProcess); Thread t = new Thread(ts); t.Name = "QueueRunningThreadProcess"; t.Start(); } } } public int Count { get { return _queue.Count; } } public long ConcurrentThreadsCount { get { return _concurrentDequeueThreadsCount; } } private void QueueRunThreadProcess() { if (_isAttachedPerformanceCounters) { _queueRunningThreadStartPerformanceCounter.Increment(); _queueRunningThreadsCountPerformanceCounter.Increment(); } if (OnQueueRunningThreadStart != null) { OnQueueRunningThreadStart ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3}({4}) at {5}" , "Queue Running Start ..." , _concurrentDequeueThreadsCount , _queue.Count , Thread.CurrentThread.Name , Thread.CurrentThread.ManagedThreadId , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } #if c2 while ((_queue.Count > 0)) //Microshaoft 死循环 #elif c4 while (!_queue.IsEmpty) //Microshaoft 死循环 #endif { int threadID = -1; { int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount); if (r < _maxConcurrentDequeueThreadsCount) { //if (_queue.Count > 0) { r = (int)Interlocked.Increment(ref _concurrentDequeueThreadsCount); threadID = (int)_concurrentDequeueThreadsCount; //ThreadProcessState tps = new ThreadProcessState(); //tps.element = element; //tps.Sender = this; Thread t = new Thread(new ThreadStart(DequeueThreadProcess)); t.TrySetApartmentState(ApartmentState.STA); t.Name = string.Format("ConcurrentDequeueProcessThread[{0}]", threadID); t.Start(); } /// else /// { /// break; /// } } else { break; } } } //Interlocked.CompareExchange(ref _queueRuning, 0, 1); if (OnQueueRunningThreadEnd != null) { int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount); OnQueueRunningThreadEnd ( string.Format ( "{0} Threads Count {1}, Queue Count {2}, Current Thread: {3}({4}) at {5}" , "Queue Running Stop ..." , r , _queue.Count , Thread.CurrentThread.Name , Thread.CurrentThread.ManagedThreadId , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } if (_isAttachedPerformanceCounters) { _queueRunningThreadEndPerformanceCounter.Increment(); _queueRunningThreadsCountPerformanceCounter.Decrement(); } Interlocked.Exchange(ref _isQueueRunning, 0); } public void Enqueue(T element) { try { #if c2 lock (_syncQueueLockObject) //还算并发吗? #endif { _queue.Enqueue(element); } if (_isAttachedPerformanceCounters) { _enqueuePerformanceCounter.Increment(); _queueLengthPerformanceCounter.Increment(); } } catch (Exception e) { if (OnException != null) { OnException(e); } } //int r = Interlocked.CompareExchange(ref _queueRuning, 1, 0)) //if (r == 1) //{ QueueRun(); //} } private void DequeueThreadProcess() { if (_isAttachedPerformanceCounters) { _dequeueThreadStartPerformanceCounter.Increment(); _dequeueThreadsCountPerformanceCounter.Increment(); } if (OnDequeueThreadStart != null) { int r = (int)Interlocked.Read(ref _concurrentDequeueThreadsCount); OnDequeueThreadStart ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}" , "Threads ++ !" , r , _queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } bool queueWasNotEmpty = false; try { #if c2 while (true) #elif c4 while (!_queue.IsEmpty) #endif { T element = null; #if c2 lock (_syncQueueLockObject) { if (_queue.Count > 0) { element = _queue.Dequeue(); } else { //避免QueueRun 死循环 break; } } #elif c4 if (_queue.TryDequeue(out element)) { #elif c2 if (element != null) { #endif if (!queueWasNotEmpty) { queueWasNotEmpty = true; } if (_isAttachedPerformanceCounters) { _dequeuePerformanceCounter.Increment(); _queueLengthPerformanceCounter.Decrement(); } if (OnDequeue != null) { OnDequeue(element); } if (_isAttachedPerformanceCounters) { _dequeueProcessedPerformanceCounter.Increment(); } #if c2 } #elif c4 } } #endif } catch (Exception e) { if (OnException != null) { OnException(e); } } finally { int r = (int)Interlocked.Decrement(ref _concurrentDequeueThreadsCount); if (OnDequeueThreadEnd != null) { OnDequeueThreadEnd ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}" , "Threads--" , r , _queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } if (r == 0) { if (OnDequeueAllThreadsEnd != null) { OnDequeueAllThreadsEnd ( string.Format ( "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}" , "All Threads End" , r , _queue.Count , Thread.CurrentThread.Name , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff") ) ); } } if (_isAttachedPerformanceCounters) { _dequeueThreadEndPerformanceCounter.Increment(); _dequeueThreadsCountPerformanceCounter.Decrement(); } if (queueWasNotEmpty) { QueueRun(); //死循环??? } } } } } namespace Microshaoft { using System; using System.Diagnostics; public static class PerformanceCounterHelper { public static CounterCreationData GetCounterCreationData(string counterName, PerformanceCounterType performanceCounterType) { CounterCreationData ccd = new CounterCreationData(); ccd.CounterName = counterName; ccd.CounterHelp = string.Format("{0} Help", counterName); ccd.CounterType = performanceCounterType; return ccd; } } } namespace Microshaoft { using System; using System.Net; using System.Net.Sockets; using System.Threading; public class SocketDataHandler { public Socket _socket; public int ReceiveBufferLength { get; private set; } private ConcurrentAsyncQueue<byte[]> _receivedAsyncQueue;//= new ConcurrentAsyncQueue<byte[]>(); private ConcurrentAsyncQueue<byte[]> _sendAsyncQueue;// = new ConcurrentAsyncQueue<byte[]>(); public delegate void DataPackReceivedEventHandler(SocketDataHandler sender, byte[] data); public event DataPackReceivedEventHandler OnSyncHeaderDataPackReceived; public event DataPackReceivedEventHandler OnSyncDataPackReceived; public event DataPackReceivedEventHandler OnAsyncQueueDataPackReceived; public IPAddress RemoteIPAddress { get { return ((IPEndPoint) _socket.RemoteEndPoint).Address; } } public IPAddress LocalIPAddress { get { return ((IPEndPoint) _socket.LocalEndPoint).Address; } } public int SocketID { get; private set; } public SocketDataHandler(Socket socket, int socketID, int receiveBufferLength) { _socket = socket; ReceiveBufferLength = receiveBufferLength; SocketID = socketID; } public int HeaderBytesLength { get; private set; } public void StartReceiveData(int headerBytesLength) { HeaderBytesLength = headerBytesLength; ThreadStart ts = new ThreadStart(ReceiveDataThreadProcess); Thread t = new Thread(ts); t.Start(); } public void ReceiveDataThreadProcess() { byte[] buffer = new byte[ReceiveBufferLength]; while (1 == 1) { int p = 0; int r = SocketDataHelper.ReadDataToFixedLengthBytes ( _socket , HeaderBytesLength , p , ref buffer ); if (r == HeaderBytesLength) { byte[] data = new byte[4]; Buffer.BlockCopy(buffer, p, data, 0, r); int l = BitConverter.ToInt32(data, 0); if (OnSyncHeaderDataPackReceived != null) { data = new byte[r]; Buffer.BlockCopy(buffer, p, data, 0, r); OnSyncHeaderDataPackReceived(this, data); } p += r; r = SocketDataHelper.ReadDataToFixedLengthBytes ( _socket , l , p , ref buffer ); if (r == l) { p += r; data = new byte[p]; Buffer.BlockCopy(buffer, 0, data, 0, data.Length); if (OnSyncDataPackReceived != null) { OnSyncDataPackReceived(this, data); } if (OnAsyncQueueDataPackReceived != null) { if (_receivedAsyncQueue == null) { _receivedAsyncQueue = new ConcurrentAsyncQueue<byte[]>(); _receivedAsyncQueue.OnDequeue += new ConcurrentAsyncQueue<byte[]>.QueueEventHandler(ReceivedQueue_OnDequeue); //_receiveQueue.OnQueueLog += new AsyncQueue<byte[]>.QueueLogEventHandler(Queue_OnQueueLog); //_receiveQueue.OnException += new AsyncQueue<byte[]>.ExceptionEventHandler(Queue_OnException); } _receivedAsyncQueue.Enqueue(data); } } } } } private object _sendSyncLockObject = new object(); public void SendDataSync(byte[] data) { lock (_sendSyncLockObject) { _socket.Send(data); } } public void SendDataAsyncQueue(byte[] data) { if (_sendAsyncQueue == null) { _sendAsyncQueue = new ConcurrentAsyncQueue<byte[]>(); _sendAsyncQueue.OnDequeue += new ConcurrentAsyncQueue<byte[]>.QueueEventHandler(SendAsyncQueue_OnDequeue); } _sendAsyncQueue.Enqueue(data); } private void SendAsyncQueue_OnDequeue(byte[] element) { SendDataSync(element); } private void ReceivedQueue_OnDequeue(byte[] element) { if (OnAsyncQueueDataPackReceived != null) { OnAsyncQueueDataPackReceived(this, element); } } } } namespace Microshaoft { using System; using System.IO; using System.Net.Sockets; public static class SocketDataHelper { public static int ReadDataToFixedLengthBytes ( Socket socket , int length , int offset , ref byte[] buffer ) { int p = offset; int l = length; int r = 0; while (p < l) { //Console.WriteLine("{0},{1}", p, l); r = socket.Receive ( buffer , p , l , SocketFlags.None ); p += r; } return r; } } } namespace Microshaoft { using System; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; public class CDATA : IXmlSerializable { private string _text; public CDATA() { } public CDATA(string text) { this._text = text; } public string Text { get { return _text; } } XmlSchema IXmlSerializable.GetSchema() { return null; } void IXmlSerializable.ReadXml(XmlReader reader) { string s = reader.ReadInnerXml(); string startTag = "<![CDATA["; string endTag = "]]>"; s = s.Trim(new char[] { '\r', '\n', '\t', ' ' }); if (s.StartsWith(startTag) && s.EndsWith(endTag)) { s = s.Substring(startTag.Length, s.LastIndexOf(endTag) - startTag.Length); } this._text = s; } void IXmlSerializable.WriteXml(XmlWriter writer) { writer.WriteCData(this._text); } } } namespace Microshaoft { using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; public static class SerializerHelper { public static T XmlToObject<T>(string Xml) { StringReader stringReader = new StringReader(Xml); XmlReader xmlReader = XmlReader.Create(stringReader); XmlSerializer serializer = new XmlSerializer(typeof(T)); return (T)serializer.Deserialize(xmlReader); } public static string ObjectToXml<T> ( T Object , XmlTextWriter writer , XmlSerializer serializer ) { serializer.Serialize(writer, Object); MemoryStream stream = writer.BaseStream as MemoryStream; byte[] bytes = stream.ToArray(); Encoding e = EncodingHelper.IdentifyEncoding ( bytes , Encoding.GetEncoding("gb2312") /// , new Encoding[] /// { /// Encoding.UTF8 /// , Encoding.Unicode /// } ); byte[] buffer = e.GetPreamble(); int offset = buffer.Length; buffer = new byte[bytes.Length - offset]; Buffer.BlockCopy(bytes, offset, buffer, 0, buffer.Length); string s = e.GetString(buffer); return s; } public static string ObjectToXml<T>(T Object, Encoding e) { XmlSerializer serializer = new XmlSerializer(typeof(T)); using (MemoryStream stream = new MemoryStream()) { XmlTextWriter writer = new XmlTextWriter(stream, e); string s = ObjectToXml<T> ( Object , writer , serializer ); writer.Close(); writer = null; return s; } } } } namespace Microshaoft { using System.IO; using System.Text; using System.Collections.Generic; public static class EncodingHelper { public static Encoding IdentifyEncoding ( Stream stream , Encoding defaultEncoding , Encoding[] identifyEncodings ) { byte[] data = StreamDataHelper.ReadDataToBytes(stream); return IdentifyEncoding ( data , defaultEncoding , identifyEncodings ); } public static Encoding IdentifyEncoding ( Stream stream , Encoding defaultEncoding ) { byte[] data = StreamDataHelper.ReadDataToBytes(stream); return IdentifyEncoding ( data , defaultEncoding ); } public static Encoding IdentifyEncoding ( byte[] data , Encoding defaultEncoding ) { EncodingInfo[] encodingInfos = Encoding.GetEncodings(); List<Encoding> list = new List<Encoding>(); foreach (EncodingInfo info in encodingInfos) { Encoding e = info.GetEncoding(); if (e.GetPreamble().Length > 0) { list.Add(e); } } Encoding[] encodings = new Encoding[list.Count]; list.CopyTo(encodings); return IdentifyEncoding ( data , defaultEncoding , encodings ); } public static Encoding IdentifyEncoding ( byte[] data , Encoding defaultEncoding , Encoding[] identifyEncodings ) { Encoding encoding = defaultEncoding; foreach (Encoding e in identifyEncodings) { byte[] buffer = e.GetPreamble(); int l = buffer.Length; if (l == 0) { continue; } bool flag = false; for (int i = 0; i < l; i++) { if (buffer[i] != data[i]) { flag = true; break; } } if (flag) { continue; } else { encoding = e; } } return encoding; } } } namespace Microshaoft { using System.IO; public static class StreamDataHelper { public static byte[] ReadDataToBytes(Stream stream) { byte[] buffer = new byte[64 * 1024]; MemoryStream ms = new MemoryStream(); int r = 0; int l = 0; long position = -1; if (stream.CanSeek) { position = stream.Position; stream.Position = 0; } while (true) { r = stream.Read(buffer, 0, buffer.Length); if (r > 0) { l += r; ms.Write(buffer, 0, r); } else { break; } } byte[] bytes = new byte[l]; ms.Position = 0; ms.Read(bytes, 0, (int)l); ms.Close(); ms.Dispose(); ms = null; if (position >= 0) { stream.Position = position; } return bytes; } } } namespace Test.Share { using System; using System.Xml.Serialization; using Microshaoft; [XmlRoot("XmlObjectMessage")] [Serializable] public class XmlObjectMessage { [XmlAttribute("From")] public string From; [XmlArrayItem("To", typeof(string))] [XmlArray("ToList")] public string[] ToList; [XmlElement("Text", typeof(CDATA))] public CDATA Text; } } //=========================================================================================== //=========================================================================================== // Server.cs // csc.exe Server.cs /r:Share.dll namespace Server { using System; using System.Text; using System.Net; using System.Net.Sockets; using Microshaoft; using Test.Share; public class SyncSocketAsyncQueueHandlerServer { public static void StartListening() { Console.Title = "Server"; 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 ..."); int i = 0; while (true) { listener.Listen(10); int id = i++; Socket socket = listener.Accept(); SocketDataHandler handler = new SocketDataHandler(socket,id, 512); Console.WriteLine("accept SocketDataHandler {0}", handler.SocketID); handler.OnAsyncQueueDataPackReceived += new SocketDataHandler.DataPackReceivedEventHandler(DataPackAsyncReceivedProcess); handler.StartReceiveData(4); } } public static void DataPackAsyncReceivedProcess(SocketDataHandler sender, byte[] data) { string s = Encoding.UTF8.GetString(data, sender.HeaderBytesLength, data.Length - sender.HeaderBytesLength); Console.WriteLine ( "received: {1}{0}{2}{0}{3}{0}[{4}]" , "\n" , sender.RemoteIPAddress.ToString() , sender.SocketID , data.Length , s ); XmlObjectMessage message = SerializerHelper.XmlToObject<XmlObjectMessage>(s); ConnectionsManager.SendDataTo ( sender , message.From , message.ToList , data ); } public static int Main(String[] args) { StartListening(); return 0; } } } namespace Server { using System; using System.Threading.Tasks; using System.Collections.Concurrent; using Microshaoft; public static class ConnectionsManager { private static ConcurrentDictionary<string , SocketDataHandler> _connections = new ConcurrentDictionary<string,SocketDataHandler>(); public static void SendDataTo ( SocketDataHandler sender , string from , string[] toList , byte[] data ) { int l = toList.Length; if (!_connections.Keys.Contains(from)) { _connections[from] = sender; } Parallel.ForEach ( toList , to => { if (_connections.Keys.Contains(to)) { SocketDataHandler toHandler = _connections[to]; Console.WriteLine ( "send: {1}{0}{2}{0}{3}" , "\n" , toHandler.RemoteIPAddress.ToString() , toHandler.SocketID , data.Length ); toHandler.SendDataAsyncQueue(data); } } ); } } } //=========================================================================================== //=========================================================================================== // Client.cs // csc.exe Client.cs /r:Share.dll namespace Client { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using Microshaoft; using Test.Share; class Program { static void Main(string[] args) { Socket socket = new Socket ( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp ); socket.Connect("127.0.0.1", 12021); SocketDataHandler handler = new SocketDataHandler(socket, 1, 512); handler.OnSyncDataPackReceived += new SocketDataHandler.DataPackReceivedEventHandler(handler_OnSyncDataPackReceived); handler.StartReceiveData(4); Console.WriteLine("please input your name:"); string from = Console.ReadLine(); Console.Title = "Client: " + from; string s = string.Empty; string text = string.Empty; string[] to = null; while ((s = Console.ReadLine()) != "q") { if (s.StartsWith("to:")) { s = s.Substring(3); to = s.Split(new char[] { ';' }); Console.WriteLine("\"to\" are ready, please input your text"); } else if (to == null) { Console.WriteLine("please input \"to\" like: \n\"to:user1;user2;user3 \""); } else { text = s; XmlObjectMessage message = new XmlObjectMessage(); message.ToList = to; message.From = from; message.Text = new CDATA(text); text = SerializerHelper.ObjectToXml<XmlObjectMessage> ( message , Encoding.UTF8 ); byte[] bodyData = Encoding.UTF8.GetBytes(text); byte[] headerData = BitConverter.GetBytes(bodyData.Length); socket.Send(headerData); socket.Send(bodyData); Console.WriteLine("Sended!"); } } } static void handler_OnSyncDataPackReceived(SocketDataHandler sender, byte[] data) { string s = Encoding.UTF8.GetString ( data , sender.HeaderBytesLength , data.Length - sender.HeaderBytesLength ); Console.WriteLine ( "received: {0},{1},[{2}]" , sender.SocketID , data.Length , s ); } } } //=========================================================================================== |