using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime;
namespace TcpScket
{
/// <summary>
/// Unicode字符集:CodePage=1200
/// </summary>
[StructLayout(LayoutKind.Explicit,CharSet=CharSet.Unicode)]
public class MessageData
{
/// <summary>
/// 数据报文分隔符:定长为16个不可显的ASCII字节(这是一个回定值)
/// </summary>
[FieldOffset(0)]
private byte[] MessageHeader ;
/// <summary>
/// 16bytes 的MD5值------非十六制格式(仅为消息体的校验)
/// </summary>
[FieldOffset(16)]
private byte[] Md5Value ;
/// <summary>
/// 数据报类型
/// </summary>
[FieldOffset(32)]
public int MessageType;
/// <summary>
/// 主消息ID-------如果为0,就表示消息是一个独立的消息(其取值一定是一个大于>0)
/// </summary>
[FieldOffset(36)]
public int MajorMessageId;
/// <summary>
/// 附消息ID-------MajorMessageId==0 就是一个独立的息;MajorMessageId!=0 是MajorMesageId消息的第( MinorMessageId) 部分
/// </summary>
[FieldOffset(40)]
public int MinorMessageId;
/// <summary>
/// 消息体的实际长度:取值为定值
/// </summary>
[FieldOffset(44)]
private int BodyLength;
/// <summary>
/// 保留值(暂时不可用)16字节
/// </summary>
[FieldOffset(48)]
private byte[] Reversed ;
/// <summary>
/// 消息体的实际数据长度(最大长度为取值为0,4,8,16,32,64,128,256,512,1024)
/// </summary>
[FieldOffset(64)]
private byte[] BodyData;
/// <summary>
/// 数据报中的数据
/// </summary>
public byte[] PacketData
{
get
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(MessageHeader, 0, 16);
ms.Write(Md5Value, 0, 16);
ms.Write(BitConverter.GetBytes(MessageType), 0, 4);
ms.Write(BitConverter.GetBytes(MajorMessageId), 0, 4);
ms.Write(BitConverter.GetBytes(MinorMessageId), 0, 4);
ms.Write(BitConverter.GetBytes(BodyLength), 0, 4);
ms.Write(Reversed, 0, 16);
if (BodyLength > 0)
{
ms.Write(BodyData, 0, BodyLength);
}
return ms.ToArray();
}
}
}
public byte[] EntityBuffer
{
get { return BodyData; }
}
public int EntityBufferSize
{
get { return BodyLength; }
}
public MessageData(int msgType, int majorMessageId, int minorMsgId, byte[] msg)
{
MessageType = msgType;
MajorMessageId = majorMessageId;
MinorMessageId = minorMsgId;
MessageHeader = MessageHelper.helperInstance.MessageHeader;
if (msg == null || msg.Length == 0)
{
Md5Value = MessageHelper.helperInstance.ComputeMd5Value(new byte[] { 0 });
}
else
{
Md5Value = MessageHelper.helperInstance.ComputeMd5Value(msg);
}
BodyLength = msg.Length;
BodyData = msg;
Reversed = new byte[16];
}
public MessageData(byte[] data)
{
MessageHeader = new byte[16];
Buffer.BlockCopy(data, 0, MessageHeader, 0, 16);
Md5Value = new byte[16];
Buffer.BlockCopy(data, 16, Md5Value, 0, 16);
MessageType = BitConverter.ToInt32(data, 32);
MajorMessageId = BitConverter.ToInt32(data, 36);
MinorMessageId = BitConverter.ToInt32(data, 40);
BodyLength = BitConverter.ToInt32(data, 44);
Reversed = new byte[16];
Buffer.BlockCopy(data, 48, Reversed, 0, 16);
if(BodyLength >0)
{
BodyData =new byte[BodyLength ];
Buffer.BlockCopy(data, 64, BodyData, 0, BodyLength);
}
}
}
public delegate void MessageDataArrivedEventHandler(object sender, MessageData data);
public sealed class MessageHelper
{
public const int CodePage = 1200;
public const string MessageHeaderStr = "MDHZDTCP";
private byte[] messageHeaderByte;
private Encoding cding;
private System.Security.Cryptography.MD5 md5;
private MessageHelper()
{
cding =Encoding.GetEncoding(1200) ;
messageHeaderByte =cding.GetBytes(MessageHeaderStr);
md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
}
public static readonly MessageHelper helperInstance = new MessageHelper();
public Encoding Encoding
{
get
{
return cding;
}
}
public Byte[] MessageHeader
{
get
{
return messageHeaderByte;
}
}
public Byte[] ComputeMd5Value(byte[] input)
{
return md5.ComputeHash(input);
}
public int IndexOfMessageHeader(byte[] buffer, int startIndex, int lastIndex)
{
if (buffer == null || buffer.Length < 16)
return -1;
if (startIndex < 0 || lastIndex >= buffer.Length || startIndex >=lastIndex )
return -1;
int mi=0;
int b = startIndex;
int len=buffer.Length ;
bool find = false;
int ipx= -1 ;
while (b <= lastIndex )
{
if (messageHeaderByte[mi] == buffer[b])
{
if(ipx ==-1)
ipx =b ;
mi++;
}
else
{
mi = 0;
ipx = -1;
}
if (mi ==16 )
{
find = true;
break;
}
b++;
}
if (!find)
return -1;
return ipx ;
}
public bool IsStartWithMessageHeaderStr(byte[] data)
{
if (data == null || data.Length < 16)
return false;
for (int i = 0; i < 16; i++)
{
if (messageHeaderByte[i] != data[i])
return false;
}
return true;
}
public bool IsComplectedPacketData(byte[] data)
{
if (data == null || data.Length < 64)
#if DEBUG
{
Console.WriteLine(" data ==null || data.Length < 64");
return false;
}
#else
return false;
#endif
if (!IsStartWithMessageHeaderStr(data))
{
#if DEBUG
Console.WriteLine(" 包头的起始值不正确!");
#endif
return false;
}
int bodyLen = BitConverter.ToInt32(data, 44);
if(data.Length !=(64+ bodyLen ))
{
return false;
}
byte[] md5Hash = null;
if (bodyLen == 0)
{
md5Hash = MessageHelper.helperInstance.ComputeMd5Value(new byte[] { 0 });
}
else
{
byte[] msg = new byte[data.Length - 64];
Buffer.BlockCopy(data, 64, msg, 0, bodyLen);
md5Hash = MessageHelper.helperInstance.ComputeMd5Value(msg);
}
for (int i = 16; i < 32; i++)
{
if (md5Hash[i - 16] != data[i])
{
return false;
}
}
return false;
}
}
public class TcpScket : IDisposable
{
protected Socket svrSkt;
private ManualResetEvent hAcceptHandle = new ManualResetEvent(true);
public List<WorketSokcet> clients = new List<WorketSokcet>();
public TcpScket(string ipAddress, int port)
{
IPAddress ip = IPAddress.Parse(ipAddress);
svrSkt = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
svrSkt.Bind(
new IPEndPoint(
ip, port));
}
public void Run(int maxBlocking)
{
svrSkt.Listen(maxBlocking);
while (true)
{
hAcceptHandle.WaitOne();
svrSkt.BeginAccept(accepteCallback, svrSkt);
hAcceptHandle.Reset();
}
}
public void RegisteredWorker(WorketSokcet ws)
{
ws.Closed += new EventHandler(ws_Closed);
clients.Add(ws);
}
void ws_Closed(object sender, EventArgs e)
{
clients.Remove((WorketSokcet)sender);
}
private void accepteCallback(IAsyncResult ar)
{
try
{
Socket sck = ar.AsyncState as Socket;
Socket workerHandle = sck.EndAccept(ar);
WorketSokcet worker = new WorketSokcet(workerHandle, this);
worker.ReceviedMessage +=new MessageDataArrivedEventHandler(worker_ReceviedMessage);
worker.Run();
}
finally
{
//无论如何都要放锁
hAcceptHandle.Set();
}
}
void worker_ReceviedMessage(object sender, MessageData e)
{
Console.WriteLine(e.MajorMessageId);
Console.WriteLine(e.MinorMessageId);
Console.WriteLine(e.MessageType);
Console.WriteLine(e.EntityBufferSize);
Console.WriteLine("=======");
}
#region IDisposable 成员
bool disposed;
private void Dispose(bool disp)
{
if (!disposed && disp)
{
if (svrSkt != null)
{
svrSkt.Shutdown(SocketShutdown.Both);
svrSkt.Close();
}
if (hAcceptHandle != null)
{
hAcceptHandle.Close();
hAcceptHandle = null;
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region 数据处理事件
public class SocketDataArrivedEventArgs : EventArgs
{
public byte[] ReceviedMessageData
{
get;
private set;
}
public SocketDataArrivedEventArgs(byte[] bufferData)
: base()
{
this.ReceviedMessageData = bufferData;
}
/// <summary>
/// 提取消息体后余下的部分数据
/// </summary>
public Byte[] LeftData
{
get;
set;
}
}
public class SocketReadDataErrorEventArgs : EventArgs
{
public SocketReadDataErrorEventArgs(SocketError se)
: base()
{
Error = se;
}
public SocketError Error
{
get;
private set;
}
/// <summary>
/// 是否取消( true: 取消继续读取数据,false :继续读取下一段数据(默认))
/// </summary>
public bool Cancel
{
get;
set;
}
}
#endregion
public class WorketSokcet : IDisposable
{
const int LEN = 1024;
static ManualResetEvent readLocker = new ManualResetEvent(true);
static ManualResetEvent writeLocker = new ManualResetEvent(true);
protected Socket mSckt;
protected byte[] mDataBuffer;
public TcpScket Parent
{
get;
private set;
}
public event EventHandler Closed;
public event EventHandler<SocketReadDataErrorEventArgs> ReadError;
public event MessageDataArrivedEventHandler ReceviedMessage;
protected BufferedStream bufferStream;
protected MemoryStream memoryStream;
protected bool disposed = false;
public WorketSokcet(Socket socket,TcpScket tcp)
{
mSckt = socket;
mDataBuffer = new byte[1024];
memoryStream = new MemoryStream();
bufferStream = new BufferedStream(memoryStream);
Parent = tcp;
}
private void readDataCallback(IAsyncResult ar)
{
ReadCallbackStateObject rs = ar.AsyncState as ReadCallbackStateObject;
SocketError se = default(SocketError);
int size = mSckt.EndReceive(ar, out se);
if (se != SocketError.Success && this.ReadError !=null )
{
SocketReadDataErrorEventArgs serr = new SocketReadDataErrorEventArgs(se);
this.ReadError(this, serr);
if (serr.Cancel)
return;
//继续接收
mSckt.BeginReceive(
rs.BufferData, 0, ReadCallbackStateObject.BufferLen,
SocketFlags.None,
out se, readDataCallback, rs
);
return;
}
if (size <= 0)
{
bufferStream.Flush();
byte[] buffered = memoryStream.ToArray();
memoryStream.Seek(0L, SeekOrigin.Begin);
memoryStream.SetLength(0L);
int lastIndex = buffered.Length - 1;
int idx = MessageHelper.helperInstance.IndexOfMessageHeader(buffered, 0, lastIndex);
int preEnd = -1;
while (idx != -1)
{
//提取消息数据
int nxt = MessageHelper.helperInstance.IndexOfMessageHeader(buffered, idx + 16, lastIndex);
if (nxt != -1)
{
int tmpLen = nxt - idx;
byte[] tmp = new byte[tmpLen];
Buffer.BlockCopy(buffered, idx, tmp, 0, tmpLen);
idx = nxt;
preEnd = nxt ;
if (MessageHelper.helperInstance.IsComplectedPacketData(tmp))
{
if (ReceviedMessage != null)
{
ReceviedMessage(this, new MessageData(tmp));
}
#if DEBUG
Console.WriteLine(MessageHelper.helperInstance.Encoding.GetString(
tmp, 64, tmp.Length - 64));
#endif
}
else
{
#if DEBUG
Console.WriteLine("ErrorMessage!");
#endif
}
}
else
{
byte[] data = new byte[buffered.Length - preEnd];
Buffer.BlockCopy(buffered, preEnd, data, 0, data.Length);
if (MessageHelper.helperInstance.IsStartWithMessageHeaderStr(data))
{
if (MessageHelper.helperInstance.IsComplectedPacketData(data))
{
if (ReceviedMessage != null)
{
ReceviedMessage(this, new MessageData(data));
}
#if DEBUG
Console.WriteLine(MessageHelper.helperInstance.Encoding.GetString(
data, 64, data.Length - 64
));
#endif
}
else
{
//不是完整的数据包
memoryStream.Write(data, 0, data.Length);
}
}
else
{
#if DEBUG
Console.WriteLine("出现非法数据");
#endif
}
idx = -1;
}
}
}
else
{
bufferStream.Write(rs.BufferData, 0, size);
//继续接收
mSckt.BeginReceive(
rs.BufferData, 0, ReadCallbackStateObject.BufferLen,
SocketFlags.None,
out se, readDataCallback, rs
);
}
}
public void Run()
{
Parent.RegisteredWorker(this);
mSckt.UseOnlyOverlappedIO = true;
SocketError se = default(SocketError);
ReadCallbackStateObject rst = new ReadCallbackStateObject();
mSckt.BeginReceive(
rst.BufferData ,0,ReadCallbackStateObject.BufferLen ,SocketFlags.None,
out se, readDataCallback,rst
);
}
#region IDisposable 成员
private void Dispose(bool disposing)
{
if (disposed == false && disposing)
{
if (bufferStream != null)
{
bufferStream.Close();
bufferStream = null;
}
if (memoryStream != null)
{
memoryStream.Close();
memoryStream = null;
}
if (mDataBuffer != null)
{
mDataBuffer = null;
}
if (mSckt != null)
{
mSckt.Shutdown(SocketShutdown.Both);
mSckt.Close();
}
if (this.Closed != null)
{
this.Closed(this, EventArgs.Empty);
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region ReadCallback
class ReadCallbackStateObject
{
public ReadCallbackStateObject()
{
BufferData = new byte[1024];
}
public Byte[] BufferData
{
get;
private set;
}
public const int BufferLen = 1024;
}
#endregion
}
}
class Program
{
static void Main(string[] args)
{
TcpScket tcs = new TcpScket("127.0.0.1", 7777);
tcs.Run(10);
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime;
namespace TcpScket
{
/// <summary>
/// Unicode字符集:CodePage=1200
/// </summary>
[StructLayout(LayoutKind.Explicit,CharSet=CharSet.Unicode)]
public class MessageData
{
/// <summary>
/// 数据报文分隔符:定长为16个不可显的ASCII字节(这是一个回定值)
/// </summary>
[FieldOffset(0)]
private byte[] MessageHeader ;
/// <summary>
/// 16bytes 的MD5值------非十六制格式(仅为消息体的校验)
/// </summary>
[FieldOffset(16)]
private byte[] Md5Value ;
/// <summary>
/// 数据报类型
/// </summary>
[FieldOffset(32)]
public int MessageType;
/// <summary>
/// 主消息ID-------如果为0,就表示消息是一个独立的消息(其取值一定是一个大于>0)
/// </summary>
[FieldOffset(36)]
public int MajorMessageId;
/// <summary>
/// 附消息ID-------MajorMessageId==0 就是一个独立的息;MajorMessageId!=0 是MajorMesageId消息的第( MinorMessageId) 部分
/// </summary>
[FieldOffset(40)]
public int MinorMessageId;
/// <summary>
/// 消息体的实际长度:取值为定值
/// </summary>
[FieldOffset(44)]
private int BodyLength;
/// <summary>
/// 保留值(暂时不可用)16字节
/// </summary>
[FieldOffset(48)]
private byte[] Reversed ;
/// <summary>
/// 消息体的实际数据长度(最大长度为取值为0,4,8,16,32,64,128,256,512,1024)
/// </summary>
[FieldOffset(64)]
private byte[] BodyData;
/// <summary>
/// 数据报中的数据
/// </summary>
public byte[] PacketData
{
get
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(MessageHeader, 0, 16);
ms.Write(Md5Value, 0, 16);
ms.Write(BitConverter.GetBytes(MessageType), 0, 4);
ms.Write(BitConverter.GetBytes(MajorMessageId), 0, 4);
ms.Write(BitConverter.GetBytes(MinorMessageId), 0, 4);
ms.Write(BitConverter.GetBytes(BodyLength), 0, 4);
ms.Write(Reversed, 0, 16);
if (BodyLength > 0)
{
ms.Write(BodyData, 0, BodyLength);
}
return ms.ToArray();
}
}
}
public byte[] EntityBuffer
{
get { return BodyData; }
}
public int EntityBufferSize
{
get { return BodyLength; }
}
public MessageData(int msgType, int majorMessageId, int minorMsgId, byte[] msg)
{
MessageType = msgType;
MajorMessageId = majorMessageId;
MinorMessageId = minorMsgId;
MessageHeader = MessageHelper.helperInstance.MessageHeader;
if (msg == null || msg.Length == 0)
{
Md5Value = MessageHelper.helperInstance.ComputeMd5Value(new byte[] { 0 });
}
else
{
Md5Value = MessageHelper.helperInstance.ComputeMd5Value(msg);
}
BodyLength = msg.Length;
BodyData = msg;
Reversed = new byte[16];
}
public MessageData(byte[] data)
{
MessageHeader = new byte[16];
Buffer.BlockCopy(data, 0, MessageHeader, 0, 16);
Md5Value = new byte[16];
Buffer.BlockCopy(data, 16, Md5Value, 0, 16);
MessageType = BitConverter.ToInt32(data, 32);
MajorMessageId = BitConverter.ToInt32(data, 36);
MinorMessageId = BitConverter.ToInt32(data, 40);
BodyLength = BitConverter.ToInt32(data, 44);
Reversed = new byte[16];
Buffer.BlockCopy(data, 48, Reversed, 0, 16);
if(BodyLength >0)
{
BodyData =new byte[BodyLength ];
Buffer.BlockCopy(data, 64, BodyData, 0, BodyLength);
}
}
}
public delegate void MessageDataArrivedEventHandler(object sender, MessageData data);
public sealed class MessageHelper
{
public const int CodePage = 1200;
public const string MessageHeaderStr = "MDHZDTCP";
private byte[] messageHeaderByte;
private Encoding cding;
private System.Security.Cryptography.MD5 md5;
private MessageHelper()
{
cding =Encoding.GetEncoding(1200) ;
messageHeaderByte =cding.GetBytes(MessageHeaderStr);
md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
}
public static readonly MessageHelper helperInstance = new MessageHelper();
public Encoding Encoding
{
get
{
return cding;
}
}
public Byte[] MessageHeader
{
get
{
return messageHeaderByte;
}
}
public Byte[] ComputeMd5Value(byte[] input)
{
return md5.ComputeHash(input);
}
public int IndexOfMessageHeader(byte[] buffer, int startIndex, int lastIndex)
{
if (buffer == null || buffer.Length < 16)
return -1;
if (startIndex < 0 || lastIndex >= buffer.Length || startIndex >=lastIndex )
return -1;
int mi=0;
int b = startIndex;
int len=buffer.Length ;
bool find = false;
int ipx= -1 ;
while (b <= lastIndex )
{
if (messageHeaderByte[mi] == buffer[b])
{
if(ipx ==-1)
ipx =b ;
mi++;
}
else
{
mi = 0;
ipx = -1;
}
if (mi ==16 )
{
find = true;
break;
}
b++;
}
if (!find)
return -1;
return ipx ;
}
public bool IsStartWithMessageHeaderStr(byte[] data)
{
if (data == null || data.Length < 16)
return false;
for (int i = 0; i < 16; i++)
{
if (messageHeaderByte[i] != data[i])
return false;
}
return true;
}
public bool IsComplectedPacketData(byte[] data)
{
if (data == null || data.Length < 64)
#if DEBUG
{
Console.WriteLine(" data ==null || data.Length < 64");
return false;
}
#else
return false;
#endif
if (!IsStartWithMessageHeaderStr(data))
{
#if DEBUG
Console.WriteLine(" 包头的起始值不正确!");
#endif
return false;
}
int bodyLen = BitConverter.ToInt32(data, 44);
if(data.Length !=(64+ bodyLen ))
{
return false;
}
byte[] md5Hash = null;
if (bodyLen == 0)
{
md5Hash = MessageHelper.helperInstance.ComputeMd5Value(new byte[] { 0 });
}
else
{
byte[] msg = new byte[data.Length - 64];
Buffer.BlockCopy(data, 64, msg, 0, bodyLen);
md5Hash = MessageHelper.helperInstance.ComputeMd5Value(msg);
}
for (int i = 16; i < 32; i++)
{
if (md5Hash[i - 16] != data[i])
{
return false;
}
}
return false;
}
}
public class TcpScket : IDisposable
{
protected Socket svrSkt;
private ManualResetEvent hAcceptHandle = new ManualResetEvent(true);
public List<WorketSokcet> clients = new List<WorketSokcet>();
public TcpScket(string ipAddress, int port)
{
IPAddress ip = IPAddress.Parse(ipAddress);
svrSkt = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
svrSkt.Bind(
new IPEndPoint(
ip, port));
}
public void Run(int maxBlocking)
{
svrSkt.Listen(maxBlocking);
while (true)
{
hAcceptHandle.WaitOne();
svrSkt.BeginAccept(accepteCallback, svrSkt);
hAcceptHandle.Reset();
}
}
public void RegisteredWorker(WorketSokcet ws)
{
ws.Closed += new EventHandler(ws_Closed);
clients.Add(ws);
}
void ws_Closed(object sender, EventArgs e)
{
clients.Remove((WorketSokcet)sender);
}
private void accepteCallback(IAsyncResult ar)
{
try
{
Socket sck = ar.AsyncState as Socket;
Socket workerHandle = sck.EndAccept(ar);
WorketSokcet worker = new WorketSokcet(workerHandle, this);
worker.ReceviedMessage +=new MessageDataArrivedEventHandler(worker_ReceviedMessage);
worker.Run();
}
finally
{
//无论如何都要放锁
hAcceptHandle.Set();
}
}
void worker_ReceviedMessage(object sender, MessageData e)
{
Console.WriteLine(e.MajorMessageId);
Console.WriteLine(e.MinorMessageId);
Console.WriteLine(e.MessageType);
Console.WriteLine(e.EntityBufferSize);
Console.WriteLine("=======");
}
#region IDisposable 成员
bool disposed;
private void Dispose(bool disp)
{
if (!disposed && disp)
{
if (svrSkt != null)
{
svrSkt.Shutdown(SocketShutdown.Both);
svrSkt.Close();
}
if (hAcceptHandle != null)
{
hAcceptHandle.Close();
hAcceptHandle = null;
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region 数据处理事件
public class SocketDataArrivedEventArgs : EventArgs
{
public byte[] ReceviedMessageData
{
get;
private set;
}
public SocketDataArrivedEventArgs(byte[] bufferData)
: base()
{
this.ReceviedMessageData = bufferData;
}
/// <summary>
/// 提取消息体后余下的部分数据
/// </summary>
public Byte[] LeftData
{
get;
set;
}
}
public class SocketReadDataErrorEventArgs : EventArgs
{
public SocketReadDataErrorEventArgs(SocketError se)
: base()
{
Error = se;
}
public SocketError Error
{
get;
private set;
}
/// <summary>
/// 是否取消( true: 取消继续读取数据,false :继续读取下一段数据(默认))
/// </summary>
public bool Cancel
{
get;
set;
}
}
#endregion
public class WorketSokcet : IDisposable
{
const int LEN = 1024;
static ManualResetEvent readLocker = new ManualResetEvent(true);
static ManualResetEvent writeLocker = new ManualResetEvent(true);
protected Socket mSckt;
protected byte[] mDataBuffer;
public TcpScket Parent
{
get;
private set;
}
public event EventHandler Closed;
public event EventHandler<SocketReadDataErrorEventArgs> ReadError;
public event MessageDataArrivedEventHandler ReceviedMessage;
protected BufferedStream bufferStream;
protected MemoryStream memoryStream;
protected bool disposed = false;
public WorketSokcet(Socket socket,TcpScket tcp)
{
mSckt = socket;
mDataBuffer = new byte[1024];
memoryStream = new MemoryStream();
bufferStream = new BufferedStream(memoryStream);
Parent = tcp;
}
private void readDataCallback(IAsyncResult ar)
{
ReadCallbackStateObject rs = ar.AsyncState as ReadCallbackStateObject;
SocketError se = default(SocketError);
int size = mSckt.EndReceive(ar, out se);
if (se != SocketError.Success && this.ReadError !=null )
{
SocketReadDataErrorEventArgs serr = new SocketReadDataErrorEventArgs(se);
this.ReadError(this, serr);
if (serr.Cancel)
return;
//继续接收
mSckt.BeginReceive(
rs.BufferData, 0, ReadCallbackStateObject.BufferLen,
SocketFlags.None,
out se, readDataCallback, rs
);
return;
}
if (size <= 0)
{
bufferStream.Flush();
byte[] buffered = memoryStream.ToArray();
memoryStream.Seek(0L, SeekOrigin.Begin);
memoryStream.SetLength(0L);
int lastIndex = buffered.Length - 1;
int idx = MessageHelper.helperInstance.IndexOfMessageHeader(buffered, 0, lastIndex);
int preEnd = -1;
while (idx != -1)
{
//提取消息数据
int nxt = MessageHelper.helperInstance.IndexOfMessageHeader(buffered, idx + 16, lastIndex);
if (nxt != -1)
{
int tmpLen = nxt - idx;
byte[] tmp = new byte[tmpLen];
Buffer.BlockCopy(buffered, idx, tmp, 0, tmpLen);
idx = nxt;
preEnd = nxt ;
if (MessageHelper.helperInstance.IsComplectedPacketData(tmp))
{
if (ReceviedMessage != null)
{
ReceviedMessage(this, new MessageData(tmp));
}
#if DEBUG
Console.WriteLine(MessageHelper.helperInstance.Encoding.GetString(
tmp, 64, tmp.Length - 64));
#endif
}
else
{
#if DEBUG
Console.WriteLine("ErrorMessage!");
#endif
}
}
else
{
byte[] data = new byte[buffered.Length - preEnd];
Buffer.BlockCopy(buffered, preEnd, data, 0, data.Length);
if (MessageHelper.helperInstance.IsStartWithMessageHeaderStr(data))
{
if (MessageHelper.helperInstance.IsComplectedPacketData(data))
{
if (ReceviedMessage != null)
{
ReceviedMessage(this, new MessageData(data));
}
#if DEBUG
Console.WriteLine(MessageHelper.helperInstance.Encoding.GetString(
data, 64, data.Length - 64
));
#endif
}
else
{
//不是完整的数据包
memoryStream.Write(data, 0, data.Length);
}
}
else
{
#if DEBUG
Console.WriteLine("出现非法数据");
#endif
}
idx = -1;
}
}
}
else
{
bufferStream.Write(rs.BufferData, 0, size);
//继续接收
mSckt.BeginReceive(
rs.BufferData, 0, ReadCallbackStateObject.BufferLen,
SocketFlags.None,
out se, readDataCallback, rs
);
}
}
public void Run()
{
Parent.RegisteredWorker(this);
mSckt.UseOnlyOverlappedIO = true;
SocketError se = default(SocketError);
ReadCallbackStateObject rst = new ReadCallbackStateObject();
mSckt.BeginReceive(
rst.BufferData ,0,ReadCallbackStateObject.BufferLen ,SocketFlags.None,
out se, readDataCallback,rst
);
}
#region IDisposable 成员
private void Dispose(bool disposing)
{
if (disposed == false && disposing)
{
if (bufferStream != null)
{
bufferStream.Close();
bufferStream = null;
}
if (memoryStream != null)
{
memoryStream.Close();
memoryStream = null;
}
if (mDataBuffer != null)
{
mDataBuffer = null;
}
if (mSckt != null)
{
mSckt.Shutdown(SocketShutdown.Both);
mSckt.Close();
}
if (this.Closed != null)
{
this.Closed(this, EventArgs.Empty);
}
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
#region ReadCallback
class ReadCallbackStateObject
{
public ReadCallbackStateObject()
{
BufferData = new byte[1024];
}
public Byte[] BufferData
{
get;
private set;
}
public const int BufferLen = 1024;
}
#endregion
}
}
class Program
{
static void Main(string[] args)
{
TcpScket tcs = new TcpScket("127.0.0.1", 7777);
tcs.Run(10);
}
}
}