//===========================================================================================
// 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
);
}
}
}
//===========================================================================================
|