http://www.cnblogs.com/zhuweisky/archive/2006/03/27/360124.html
http://blog.csdn.net/zhuweisky/article/details/4608945
//-----------------------------------
#region InstantMessageContract
public class InstantMessageContract : IContract
{
#region Members
public int MessageTextLen; //消息文本长度
public string MessageText; //消息文本
#endregion
#region Ctor
private IStringEncoder stringEncoder;
public InstantMessageContract(IStringEncoder encoder)
{
this.stringEncoder = encoder;
}
#endregion
#region IContract 成员
#region FillMyself
public void FillMyself(byte[] data, int offset)
{
int curOffset = offset;
this.MessageTextLen = BitConverter.ToInt32(data, curOffset);
curOffset += 4;
this.MessageText = this.stringEncoder.GetStrFromStream(data, curOffset, this.MessageTextLen);
curOffset += this.MessageTextLen;
}
#endregion
#region GetStreamLength
public int GetStreamLength()
{
int totalLen = 4 + this.MessageTextLen;
return totalLen;
}
#endregion
#region ToStream
public byte[] ToStream()
{
int totalLen = this.GetStreamLength();
byte[] stream = new byte[totalLen];
int offset = 0;
#region FillFields
byte[] bMessageTextLen = BitConverter.GetBytes(this.MessageTextLen);
for (int i = 0; i < bMessageTextLen.Length; i++)
{
stream[offset + i] = bMessageTextLen[i];
}
offset += 4;
byte[] bMessageText = this.stringEncoder.GetBytesFromStr(this.MessageText);
for (int i = 0; i < bMessageText.Length; i++)
{
stream[offset + i] = bMessageText[i];
}
offset += bMessageText.Length;
#endregion
return stream;
}
#endregion
#region ToStream2
public void ToStream(byte[] buff, int offset)
{
byte[] stream = this.ToStream();
for (int i = 0; i < stream.Length; i++)
{
buff[offset + i] = stream[i];
}
}
#endregion
#endregion
}
#endregion
//------------------------------------
[Serializable]
public class ContractHelper : IContractHelper, IServiceKeyNameMatcher, ITcpPassiveHelper, IStringEncoder
{
private int serverType = 0x1b;
public IMessageHeader CreateMessageHeader(string userID, int serviceKey, int bodyLen)
{
MessageHeader header = new MessageHeader(this);
header.UserID = userID;
header.UserIDLen = this.GetBytesFromStr(userID).Length;
header.ServiceKey = serviceKey;
header.MessageBodyLength = bodyLen;
return header;
}
public byte[] GetBytesFromStr(string ss)
{
if (ss == null)
{
return new byte[0];
}
return Encoding.Default.GetBytes(ss);
}
public string GetFailureMsg(int serviceResultType)
{
return ServiceResultType.MatchServiceResultType(serviceResultType);
}
public NetMessage GetResponseByServiceResultType(NetMessage reqMsg, int serviceResultType)
{
IMessageHeader header = (IMessageHeader) reqMsg.Header.Clone();
header.MessageBodyLength = 0;
header.Result = serviceResultType;
return new NetMessage(header, null);
}
public string GetServiceName(int serviceKey)
{
return serviceKey.ToString();
}
public ServiceType GetServiceType(int serviceKey)
{
if ((serviceKey >= 20) && (serviceKey < 39))
{
return ServiceType.Basic;
}
if ((serviceKey >= 40) && (serviceKey < 59))
{
return ServiceType.P2PMessage;
}
if ((serviceKey >= 60) && (serviceKey < 89))
{
return ServiceType.FriendRelation;
}
if ((serviceKey > 900) && (serviceKey < 999))
{
return ServiceType.Function;
}
return ServiceType.CustomServiceType;
}
public string GetStrFromStream(byte[] stream, int offset, int len)
{
if (stream == null)
{
return null;
}
return Encoding.Default.GetString(stream, offset, len);
}
public IMessageHeader ParseMessageHeader(byte[] data, int offset)
{
MessageHeader header = new MessageHeader(this);
header.FillMyself(data, offset);
return header;
}
public bool ValidateMessageToken(IMessageHeader header)
{
return (((MessageHeader) header).Token == "@@@@");
}
public bool VerifyFirstMessage(NetMessage msg)
{
return true;
}
public bool VerifyOtherMessage(NetMessage msg)
{
return true;
}
public int MessageHeaderLength
{
get
{
return 96;
}
}
public int ServerType
{
get
{
return this.serverType;
}
set
{
this.serverType = value;
}
}
}
//-------------------------------------------
public class ContractParser : IPassiveHelper
{
#region property
#region ContractHelper
private IContractHelper contractHelper;
public IContractHelper ContractHelper
{
set
{
this.contractHelper = value;
}
}
#endregion
#endregion
#region ParseBody
public IContract ParseBody(int serviceKey, byte[] data)
{
return this.ParseBody(serviceKey, data, 0);
}
public IContract ParseBody(int serviceKey, byte[] data, int offset)
{
if ((data == null) || (data.Length <= offset))
{
return null;
}
if (this.contractHelper.GetServiceType(serviceKey) == ServiceType.P2PMessage)
{
IContract contract = P2PRequestType.GetEmptyContract(serviceKey, this.contractHelper);
if (contract != null)
{
contract.FillMyself(data, offset);
}
return contract;
}
if (this.contractHelper.GetServiceType(serviceKey) == ServiceType.FriendRelation)
{
IContract contract = FriendRelationRequestType.GetEmptyContract(serviceKey, this.contractHelper);
if (contract != null)
{
contract.FillMyself(data, offset);
}
return contract;
}
return null;
}
#endregion
#region ParseServiceFailureBody
public IServiceFailureBody ParseServiceFailureBody(byte[] body)
{
return null;
}
#endregion
#region IContractParser Members
public PassiveMessageType GetPassiveMessageType(IMessageHeader header)
{
int serviceKey = header.ServiceKey;
if (header.P2PAck)
{
return PassiveMessageType.Ack;
}
if (this.contractHelper.GetServiceType(serviceKey) == ServiceType.P2PMessage)
{
return PassiveMessageType.P2PMessage;
}
if ((serviceKey == DataCenterBase.RequestTypeDefinition.LogonAgin) || ((serviceKey == FriendRelationRequestType.ChangeMyState)))
{
return PassiveMessageType.Notify;
}
if ((this.contractHelper.GetServiceType(serviceKey) == ServiceType.Basic) || (this.contractHelper.GetServiceType(serviceKey) == ServiceType.FriendRelation) || (this.contractHelper.GetServiceType(serviceKey) == ServiceType.Function))
{
return PassiveMessageType.Response;
}
return PassiveMessageType.Response;
}
#endregion
}
//-------------------------------------
public class ServerProxy
{
#region property
#region MyID
private string myID = "";
public string MyID
{
set
{
this.myID = value;
}
}
#endregion
#region DataEntryToUserDb
private IDataEntry dataEntryToUserDb = null;
public IDataEntry DataEntryToUserDb
{
set
{
this.dataEntryToUserDb = value;
}
}
#endregion
#region ContractParser
private ContractParser contractParser = null;
public ContractParser ContractParser
{
set
{
this.contractParser = value;
}
}
#endregion
#region ContractHelper
private IContractHelper contractHelper = null;
public IContractHelper ContractHelper
{
get
{
return this.contractHelper;
}
set
{
this.contractHelper = value;
}
}
#endregion
#region TcpServerAgent
private ITcpServerAgent tcpServerAgent = null;
public ITcpServerAgent TcpServerAgent
{
get
{
return this.tcpServerAgent;
}
set
{
this.tcpServerAgent = value;
}
}
#endregion
#region FilePackageSize
private int filePackageSize = 2000;//bytes
public int FilePackageSize
{
set
{
this.filePackageSize = value;
}
}
#endregion
#endregion
#region Friends
public ArrayList GetAllFriends()
{
ArrayList list = new ArrayList();
ClientUser[] friends = (ClientUser[])this.dataEntryToUserDb.GetObjects(typeof(ClientUser), "") ;
if (friends != null)
{
foreach (ClientUser friend in friends)
{
list.Add(friend);
}
}
return list;
}
public ClientUser GetUser(string userID)
{
return (ClientUser)this.dataEntryToUserDb.GetAObjectEspecial(typeof(ClientUser), userID);
}
public Hashtable GetAllOnlineFriendStatus() //ID -- status
{
Hashtable ht = new Hashtable();
IMessageHeader header = this.CreateMessageHeader(FriendRelationRequestType.FriendList, 0);
NetMessage result = this.tcpServerAgent.CommitRequest(new Message(header ,null) ,DataPriority.Common, true);
if (result.Header.Result != ServiceResultType.ServiceSucceed)
{
return ht;
}
FriendsStatusContract contract = (FriendsStatusContract)this.contractParser.ParseBody(result.Header.ServiceKey ,result.Body ,result.BodyOffset);
foreach (TheStatus theStatus in contract.theTheStatuss)
{
ht.Add(theStatus.FriendID, theStatus.Status);
}
return ht;
}
#endregion
#region Basic
#region CreateMessageHeader
public MessageHeader CreateMessageHeader(int serviceKey, int bodyLen)
{
return this.CreateMessageHeader(serviceKey, bodyLen, null);
}
public MessageHeader CreateMessageHeader(int serviceKey, int bodyLen ,string destID)
{
MessageHeader header = (MessageHeader)((ITcpPassiveHelper)this.contractHelper).CreateMessageHeader(this.myID, serviceKey, bodyLen);
if (destID != null)
{
header.DestUserID = destID;
header.DestUserIDLen = this.contractHelper.GetBytesFromStr(destID).Length;
}
return header;
}
#endregion
#region GetFailureMsg
public string GetFailureMsg(int resultKey)
{
return ((ITcpPassiveHelper)this.contractHelper).GetFailureMsg(resultKey);
}
#endregion
#endregion
#region Logon
public bool Logon()
{
MessageHeader header = this.CreateMessageHeader(RequestTypeDefinition.Logon, 0);
NetMessage respond = this.tcpServerAgent.CommitRequest(new Message(header, null), DataPriority.Common, true);
return respond.Header.Result == ServiceResultType.ServiceSucceed;
}
public void Logout()
{
MessageHeader header = this.CreateMessageHeader(RequestTypeDefinition.Logout, 0);
this.tcpServerAgent.CommitRequest(new Message(header, null), DataPriority.Common, false);
}
#endregion
#region SendCheckMessage
public void SendCheckMessage()
{
MessageHeader header = this.CreateMessageHeader(RequestTypeDefinition.Check, 0);
this.tcpServerAgent.CommitRequest(new Message(header, null), DataPriority.High, false);
}
#endregion
#region SendInstantMsg
public void SendInstantMsg(string friendID, string msg)
{
InstantMessageContract contract = new InstantMessageContract(this.contractHelper);
contract.MessageText = msg;
contract.MessageTextLen = this.contractHelper.GetBytesFromStr(contract.MessageText).Length;
MessageHeader header = (MessageHeader)((ITcpPassiveHelper)this.contractHelper).CreateMessageHeader(this.myID, P2PRequestType.InstantMessage, contract.GetStreamLength());
header.DestUserID = friendID;
header.DestUserIDLen = this.contractHelper.GetBytesFromStr(header.DestUserID).Length;
this.tcpServerAgent.CommitRequest(new ESFramework.Network.Message(header, contract), DataPriority.Common, false);
}
#endregion
#region File
#region SendTransFileQuery
public void SendTransFileQuery(string destID, string fileName, int fileSize)
{
FileTransmitQueryContract contract = (FileTransmitQueryContract)P2PRequestType.GetEmptyContract(P2PRequestType.FileTransmitQuery, this.contractHelper);
contract.FileName = fileName;
contract.FileNameLen = this.contractHelper.GetBytesFromStr(fileName).Length;
contract.FileLength = fileSize;
MessageHeader header = this.CreateMessageHeader(P2PRequestType.FileTransmitQuery ,contract.GetStreamLength() ,destID) ;
this.tcpServerAgent.CommitRequest(new Message(header, contract), DataPriority.Common, false);
}
#endregion
#region CreateFileTransmitter
public IFileTransmitter CreateFileTransmitter(string friendID, string filePath)
{
MessageHeader header = this.CreateMessageHeader(P2PRequestType.FileTransmit, 0, friendID);
FilePackageContract contract = new FilePackageContract(this.contractHelper);
Message packMsg = new Message(header, contract);
IFileTransmitter transmitter = new FileTransmitter(this.tcpServerAgent, (ITcpPassiveHelper)this.contractHelper, packMsg, filePath);
//transmitter.AckChecked = true;
transmitter.FileDataPriority = DataPriority.Low;
transmitter.SendingSpan = 100;
transmitter.PackageSize = this.filePackageSize;
return transmitter;
}
#endregion
#region SendFileTransmitRespond
public void SendFileTransmitRespond(string destID ,bool agree)
{
FileTransmitRespondContract contract = (FileTransmitRespondContract)P2PRequestType.GetEmptyContract(P2PRequestType.FileTransmitRespond, this.contractHelper);
contract.Accept = agree ? 1 : 0;
MessageHeader header = this.CreateMessageHeader(P2PRequestType.FileTransmitRespond, contract.GetStreamLength(), destID);
this.tcpServerAgent.CommitRequest(new Message(header, contract),DataPriority.Common , false);
}
#endregion
#region SendCancelFileTransmit
public void SendCancelFileTransmit(string destID)
{
MessageHeader header = this.CreateMessageHeader(P2PRequestType.FileTransmitCancel, 0, destID);
this.tcpServerAgent.CommitRequest(new Message(header, null),DataPriority.Common , false);
this.tcpServerAgent.ClearQueue(DataPriority.Low);
}
#endregion
#endregion
#region AV
public void SendAVRespond(bool agree ,string destID)
{
AVRespondContract contract = (AVRespondContract)P2PRequestType.GetEmptyContract(P2PRequestType.AVRespond, this.contractHelper);
contract.Agree = agree ? 1 : 0;
MessageHeader header = this.CreateMessageHeader(P2PRequestType.AVRespond, contract.GetStreamLength(), destID);
this.tcpServerAgent.CommitRequest(new Message(header, contract), DataPriority.Common, false);
}
public void SendAVQuery(string destID)
{
MessageHeader header = this.CreateMessageHeader(P2PRequestType.AVQuery, 0 ,destID);
this.tcpServerAgent.CommitRequest(new Message(header, null), DataPriority.Common, false);
}
public void SendAudio(string destID, byte[] audioData)
{
AudioContract contract = new AudioContract(this.contractHelper);
contract.DataLen = audioData.Length;
contract.Data = audioData;
MessageHeader header = this.CreateMessageHeader(P2PRequestType.AudioMessage, contract.GetStreamLength(), destID);
this.tcpServerAgent.CommitRequest(new Message(header, contract), DataPriority.CanBeDiscarded, false);
}
public void SendVideo(string destID, Bitmap bitmap)
{
VideoContract contract = new VideoContract(this.contractHelper);
byte[] jpgImg = ESFramework.Common.AdvancedFunction.CompressBitmapToJpg(bitmap);
contract.DataLen = jpgImg.Length;
contract.Data = jpgImg;
MessageHeader header = this.CreateMessageHeader(P2PRequestType.VideoMessage, contract.GetStreamLength(), destID);
this.tcpServerAgent.CommitRequest(new Message(header, contract), DataPriority.CanBeDiscarded, false);
}
public void SendAVCancel(string destID)
{
MessageHeader header = this.CreateMessageHeader(P2PRequestType.AVCancel, 0, destID);
this.tcpServerAgent.CommitRequest(new Message(header, null), DataPriority.Common, false);
}
#endregion
}
//-----------------------服务端------------------
public class AsynTcp : ITcp, INet, ITcpEventList, ITcpClientsController
{
public event CbSimpleInt ConnectionCountChanged;
public event CbSimpleStr DynamicMsgArrived;
public event CallBackForTcpMonitor ServiceCommitted;
public event CallBackForTcpMonitor ServiceDirectCommitted;
public event CbSimpleInt SomeOneConnected;
public event CallBackForTcpUser1 SomeOneDisConnected;
public event CallBackForTcpUser UserAction;
public AsynTcp()
{
this.xtcpListener = null;
this.messageDispatcher = null;
this.contextKeyMgr = new ContextKeyManager();
this.stateIsStop = true;
this.validateRequest = false;
this.curPort = 0x22b8;
}
private void ActivateUserActionEvent(int ConnectID, TcpUserAction action)
{
if (this.UserAction != null)
{
this.UserAction(ConnectID, action);
}
}
private bool CheckData(ContextKey key)
{
int num1 = key.NetStream.GetHashCode();
if (this.stateIsStop)
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
return false;
}
if (key.BytesRead == 0)
{
this.DisposeOneConnection(num1, DisconnectedCause.LineOff);
return false;
}
if (key.BytesRead == 8)
{
string text1 = Encoding.BigEndianUnicode.GetString(key.Buffer, 0, 8);
this.DisposeOneConnection(num1, DisconnectedCause.LineOff);
return false;
}
return true;
}
private void DisposeOneConnection(int connectID)
{
this.contextKeyMgr.RemoveContextKey(connectID);
}
public void DisposeOneConnection(int connectID, DisconnectedCause cause)
{
this.DisposeOneConnection(connectID);
if (this.SomeOneDisConnected != null)
{
this.SomeOneDisConnected(connectID, cause);
}
this.ActivateUserActionEvent(connectID, TcpUserAction.Exit);
}
public NetAddinType GetProtocalType()
{
return NetAddinType.Tcp;
}
public void InitializeAll()
{
this.xtcpListener = new XTcpListener(this.curPort);
this.xtcpListener.TcpConnectionEstablished += new CBackUserLogon(this.xtcpListener_TcpConnectionEstablished);
this.xtcpListener.DynamicMsgArrived += new CbSimpleStr(this.PutoutDynamicMsg);
this.contextKeyMgr.StreamCountChanged += new CbSimpleInt(this.OnStreamCountChanged);
}
private void OnStreamCountChanged(int count)
{
if (this.ConnectionCountChanged != null)
{
this.ConnectionCountChanged(count);
}
}
private void PutoutDynamicMsg(string msg)
{
if (this.DynamicMsgArrived != null)
{
this.DynamicMsgArrived(msg);
}
}
private void RecieveDataFrom(ContextKey key)
{
key.StreamState = NetStreamState.Reading;
key.NetStream.BeginRead(key.Buffer, key.StartOffsetForRecieve, key.MaxRecieveCapacity, new AsyncCallback(this.ServeOverLap), key);
}
public void SendData(int ConnectID, byte[] data)
{
this.SendData(ConnectID, data, 0, data.Length);
}
public void SendData(int ConnectID, byte[] data, int offset, int size)
{
if ((((data != null) && (data.Length != 0)) && ((offset >= 0) && (size >= 0))) && ((offset + size) <= data.Length))
{
ISafeNetworkStream stream1 = this.contextKeyMgr.GetNetStream(ConnectID);
if (stream1 != null)
{
stream1.Write(data, offset, size);
if (this.ServiceDirectCommitted != null)
{
RespondInformation information1 = new RespondInformation();
information1.ConnectID = ConnectID;
information1.ServiceKey = -1;
if ((offset == 0) && (size == data.Length))
{
information1.repondData = data;
}
else
{
information1.repondData = new byte[size];
for (int num1 = 0; num1 < size; num1++)
{
information1.repondData[num1] = data[offset + num1];
}
}
this.ServiceDirectCommitted(information1);
}
}
}
}
private void ServeOverLap(IAsyncResult ar)
{
ContextKey key1 = (ContextKey) ar.AsyncState;
int num1 = key1.NetStream.GetHashCode();
try
{
key1.BytesRead = key1.NetStream.EndRead(ar);
if (!this.CheckData(key1))
{
return;
}
byte[] buffer1 = null;
ArrayList list1 = this.messageDispatcher.DealRequestMessage(key1.RequestData, out buffer1, ref key1.Validation);
if (this.validateRequest && key1.Validation.gotoCloseConnection)
{
this.DisposeOneConnection(num1, key1.Validation.cause);
}
key1.StreamState = NetStreamState.Writing;
if ((list1 != null) && (list1.Count != 0))
{
foreach (object obj1 in list1)
{
byte[] buffer2 = (byte[]) obj1;
key1.NetStream.Write(buffer2, 0, buffer2.Length);
if (this.ServiceCommitted != null)
{
RespondInformation information1 = new RespondInformation();
information1.ConnectID = num1;
information1.ServiceKey = this.messageDispatcher.GetServiceKey(buffer2);
information1.repondData = buffer2;
this.ServiceCommitted(information1);
}
this.ActivateUserActionEvent(num1, TcpUserAction.FunctionAccess);
}
}
if (key1.IsFirstMsg)
{
if ((list1 == null) || (list1.Count == 0))
{
key1.IsFirstMsg = true;
}
else
{
key1.IsFirstMsg = false;
}
}
key1.StreamState = NetStreamState.Idle;
key1.ResetBuffer(buffer1);
if (!this.stateIsStop)
{
this.RecieveDataFrom(key1);
}
else
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
}
}
catch (Exception exception1)
{
if (exception1 is IOException)
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
}
exception1 = exception1;
}
}
public void Start()
{
if (this.stateIsStop)
{
this.xtcpListener.Start();
this.stateIsStop = false;
}
}
public void Stop()
{
if (!this.stateIsStop)
{
this.stateIsStop = true;
this.xtcpListener.Stop();
int num1 = 0;
while (!this.contextKeyMgr.IsAllStreamSafeToStop())
{
Thread.Sleep(200);
if (10 == num1++)
{
break;
}
}
this.contextKeyMgr.DisposeAllContextKey();
}
}
public bool SynRecieveFrom(int ConnectID, byte[] buffer, int offset, int size, out int readCount)
{
readCount = 0;
ISafeNetworkStream stream1 = this.contextKeyMgr.GetNetStream(ConnectID);
if (stream1 == null)
{
return false;
}
readCount = stream1.Read(buffer, offset, size);
return true;
}
public void UnitializeAll()
{
this.Stop();
this.xtcpListener.ExitListenThread();
this.ConnectionCountChanged = null;
this.DynamicMsgArrived = null;
this.ServiceCommitted = null;
this.ServiceDirectCommitted = null;
this.SomeOneConnected = null;
this.SomeOneDisConnected = null;
this.UserAction = null;
}
private void xtcpListener_TcpConnectionEstablished(NetworkStream stream)
{
ISafeNetworkStream stream1 = new SafeNetworkStream(stream);
ContextKey key1 = new ContextKey(stream1,1024);
key1.ResetBuffer(null);
this.contextKeyMgr.InsertContextKey(key1);
int num1 = key1.NetStream.GetHashCode();
if (this.SomeOneConnected != null)
{
this.SomeOneConnected(num1);
}
this.ActivateUserActionEvent(num1, TcpUserAction.Logon);
key1.IsFirstMsg = true;
this.RecieveDataFrom(key1);
}
public int ConnectionCount
{
get
{
return this.contextKeyMgr.ConnectionCount;
}
}
public IReqestStreamDispatcher Dispatcher
{
set
{
this.messageDispatcher = (ITcpReqStreamDispatcher) value;
}
}
public int Port
{
get
{
return this.curPort;
}
set
{
this.curPort = value;
}
}
public bool UserValidated
{
set
{
this.validateRequest = value;
}
}
private const int BufferSize = 1024;
private ContextKeyManager contextKeyMgr;
private int curPort;
private ITcpReqStreamDispatcher messageDispatcher;
private bool stateIsStop;
private bool validateRequest;
private IXTcpListener xtcpListener;
}
//---------------------------------------------------
public class ContextKey
{
public ContextKey(ISafeNetworkStream net_Stream, int buffSize)
{
this.LeftDataMaxPercent = 0.66;
this.bytesRead = 0;
this.netStream = null;
this.preLeftDataLen = 0;
this.streamState = NetStreamState.Idle;
this.netStream = net_Stream;
this.requestData = new EnterpriseServerBase.Network.Tcp.RequestData();
this.requestData.Buff = new byte[buffSize];
this.requestData.ConnectID = this.netStream.GetHashCode();
this.Validation = new RequestValidation();
}
public void ResetBuffer(byte[] leftData)
{
this.BytesRead = 0;
for (int num1 = 0; num1 < this.Buffer.Length; num1++)
{
this.Buffer[num1] = 0;
}
this.preLeftDataLen = 0;
if ((leftData != null) && (leftData.Length <= (this.LeftDataMaxPercent * this.Buffer.Length)))
{
this.preLeftDataLen = leftData.Length;
for (int num2 = 0; num2 < leftData.Length; num2++)
{
this.Buffer[num2] = leftData[num2];
}
}
}
public byte[] Buffer
{
get
{
return this.requestData.Buff;
}
set
{
this.requestData.Buff = value;
}
}
public int BytesRead
{
get
{
return this.bytesRead;
}
set
{
this.bytesRead = value;
this.requestData.ValidCount = this.bytesRead + this.preLeftDataLen;
}
}
public bool IsFirstMsg
{
get
{
return this.requestData.IsFirstMsg;
}
set
{
this.requestData.IsFirstMsg = value;
}
}
public int MaxRecieveCapacity
{
get
{
return (this.Buffer.Length - this.preLeftDataLen);
}
}
public ISafeNetworkStream NetStream
{
get
{
return this.netStream;
}
}
public int PreLeftDataLen
{
get
{
return this.preLeftDataLen;
}
set
{
this.preLeftDataLen = value;
}
}
public EnterpriseServerBase.Network.Tcp.RequestData RequestData
{
get
{
return this.requestData;
}
}
public int StartOffsetForRecieve
{
get
{
return this.preLeftDataLen;
}
}
public NetStreamState StreamState
{
get
{
return this.streamState;
}
set
{
this.streamState = value;
}
}
private int bytesRead;
private double LeftDataMaxPercent;
private ISafeNetworkStream netStream;
private int preLeftDataLen;
private EnterpriseServerBase.Network.Tcp.RequestData requestData;
private NetStreamState streamState;
public RequestValidation Validation;
}
//-----------------------服务端------------------------
public class XTcpListener : IXTcpListener
{
public event CbSimpleStr DynamicMsgArrived;
public event CBackUserLogon TcpConnectionEstablished;
public XTcpListener(int port)
{
this.tcpListener = null;
this.currentListenThread = null;
this.stateIsStop = true;
this.toExitListenThread = false;
this.listenThreadStoppedSafe = true;
this.tcpListener = new TcpListener(port);
}
public void ExitListenThread()
{
this.Stop();
this.toExitListenThread = true;
while (!this.listenThreadStoppedSafe)
{
Thread.Sleep(200);
}
}
private void ListenThreadMethod()
{
try
{
this.listenThreadStoppedSafe = false;
while (!this.toExitListenThread)
{
if (this.stateIsStop)
{
Thread.Sleep(100);
continue;
}
if (!this.tcpListener.Pending())
{
Thread.Sleep(100);
continue;
}
TcpClient client1 = this.tcpListener.AcceptTcpClient();
if (this.TcpConnectionEstablished != null)
{
this.TcpConnectionEstablished(client1.GetStream());
}
}
this.listenThreadStoppedSafe = true;
}
catch (Exception exception1)
{
string text1 = exception1.Message;
this.PutoutDynamicMsg(text1);
}
}
private void PutoutDynamicMsg(string msg)
{
if (this.DynamicMsgArrived != null)
{
this.DynamicMsgArrived(msg);
}
}
public void Start()
{
if (this.stateIsStop)
{
this.tcpListener.Start();
this.stateIsStop = false;
if ((this.currentListenThread == null) || !this.currentListenThread.IsAlive)
{
this.currentListenThread = new Thread(new ThreadStart(this.ListenThreadMethod));
this.currentListenThread.Start();
this.toExitListenThread = false;
string text1 = "currentListenThread线程启动";
this.PutoutDynamicMsg(text1);
}
}
}
public void Stop()
{
if (!this.stateIsStop)
{
this.tcpListener.Stop();
this.stateIsStop = true;
}
}
private Thread currentListenThread;
private bool listenThreadStoppedSafe;
private bool stateIsStop;
private TcpListener tcpListener;
private bool toExitListenThread;
}
//---------------------------客户端-------------------------
public class AgileTcp : ITcp, ITcpClientsController, IDisposable
{
private IBufferPool bufferPool;
private IContextKeyManager contextKeyManager = new ContextKeyManager();
private IContractHelper contractHelper;
private IEsbLogger esbLogger = new EmptyEsbLogger();
private IEsfTcpListener esfTcpListener = null;
private int maxMessageSize = 0xf4240;
private int port = 0x1f40;
private int recieveBuffSize = 0x400;
private volatile bool stop = true;
private ITcpStreamDispatcher tcpStreamDispatcher = null;
public event CbSimpleInt ConnectionCountChanged;
public event CallBackRespond ServiceCommitted;
public event CallBackRespond ServiceDirectCommitted;
public event CbSimpleInt SomeOneConnected;
public event CallBackDisconnect SomeOneDisConnected;
private void contextKeyManager_StreamCountChanged(int val)
{
if (this.ConnectionCountChanged != null)
{
this.ConnectionCountChanged(val);
}
}
private void DataManaging(ContextKey key)
{
int hashCode = key.NetStream.GetHashCode();
int messageHeaderLength = this.contractHelper.MessageHeaderLength;
while (key.NetStream.DataAvailable && !this.stop)
{
byte[] buff = null;
try
{
NetHelper.RecieveData(key.NetStream, key.Buffer, 0, messageHeaderLength);
IMessageHeader header = this.contractHelper.ParseMessageHeader(key.Buffer, 0);
if (!this.contractHelper.ValidateMessageToken(header))
{
this.DisposeOneConnection(hashCode, DisconnectedCause.MessageTokenInvalid);
return;
}
RoundedMessage reqMsg = new RoundedMessage();
reqMsg.ConnectID = hashCode;
reqMsg.Header = header;
if (!key.FirstMessageExist)
{
reqMsg.IsFirstMessage = true;
key.FirstMessageExist = true;
}
if ((messageHeaderLength + header.MessageBodyLength) > this.maxMessageSize)
{
this.DisposeOneConnection(hashCode, DisconnectedCause.MessageSizeOverflow);
return;
}
if (header.MessageBodyLength > 0)
{
if ((header.MessageBodyLength + messageHeaderLength) <= this.recieveBuffSize)
{
NetHelper.RecieveData(key.NetStream, key.Buffer, 0, header.MessageBodyLength);
reqMsg.Body = key.Buffer;
}
else
{
buff = this.bufferPool.RentBuffer(header.MessageBodyLength);
NetHelper.RecieveData(key.NetStream, buff, 0, header.MessageBodyLength);
reqMsg.Body = buff;
}
}
bool closeConnection = false;
NetMessage msg = this.tcpStreamDispatcher.DealRequestData(reqMsg, ref closeConnection);
if (buff != null)
{
this.bufferPool.GivebackBuffer(buff);
}
if (closeConnection)
{
this.DisposeOneConnection(hashCode, DisconnectedCause.OtherCause);
return;
}
if ((msg != null) && !this.stop)
{
byte[] buffer = msg.ToStream();
key.NetStream.Write(buffer, 0, buffer.Length);
if (this.ServiceCommitted != null)
{
this.ServiceCommitted(hashCode, msg);
}
}
continue;
}
catch (Exception exception)
{
if (exception is IOException)
{
this.DisposeOneConnection(hashCode, DisconnectedCause.NetworkError);
break;
}
this.esbLogger.Log(exception.Message, "ESFramework.Network.Tcp.AgileTcp", ErrorLevel.Standard);
exception = exception;
continue;
}
}
key.IsDataManaging = false;
}
public void Dispose()
{
this.Stop();
this.esfTcpListener.Dispose();
}
public void DisposeOneConnection(int connectID, DisconnectedCause cause)
{
this.contextKeyManager.RemoveContextKey(connectID);
if (this.SomeOneDisConnected != null)
{
this.SomeOneDisConnected(connectID, cause);
}
}
private void esfTcpListener_TcpConnectionEstablished(NetworkStream stream)
{
ISafeNetworkStream stream2 = new SafeNetworkStream(stream);
ContextKey key = new ContextKey(stream2, this.recieveBuffSize);
this.contextKeyManager.InsertContextKey(key);
int hashCode = key.NetStream.GetHashCode();
if (this.SomeOneConnected != null)
{
this.SomeOneConnected(hashCode);
}
}
public void Initialize()
{
this.esfTcpListener = new EsfTcpListener(this.port);
this.esfTcpListener.TcpConnectionEstablished += new CBackConnection(this.esfTcpListener_TcpConnectionEstablished);
this.contextKeyManager.StreamCountChanged += new CbSimpleInt(this.contextKeyManager_StreamCountChanged);
}
public void SendData(int ConnectID, NetMessage msg)
{
if (msg != null)
{
ISafeNetworkStream netStream = this.contextKeyManager.GetNetStream(ConnectID);
if (netStream != null)
{
try
{
byte[] buffer = msg.ToStream();
netStream.Write(buffer, 0, buffer.Length);
if (this.ServiceDirectCommitted != null)
{
this.ServiceDirectCommitted(ConnectID, msg);
}
}
catch (Exception exception)
{
if (exception is IOException)
{
this.DisposeOneConnection(ConnectID, DisconnectedCause.NetworkError);
}
throw exception;
}
}
}
}
public void Start()
{
if (this.stop)
{
this.stop = false;
this.esfTcpListener.Start();
new CbSimple(this.TaskChecker).BeginInvoke(null, null);
}
}
public void Stop()
{
if (!this.stop)
{
this.stop = true;
this.esfTcpListener.Stop();
this.contextKeyManager.DisposeAllContextKey();
}
}
private void TaskChecker()
{
while (!this.stop)
{
foreach (ContextKey key in this.contextKeyManager.ContextKeyList)
{
if (this.stop)
{
break;
}
if (!key.IsDataManaging && key.NetStream.DataAvailable)
{
key.IsDataManaging = true;
new CbContextKey(this.DataManaging).BeginInvoke(key, null, null);
}
}
Thread.Sleep(50);
}
}
public IBufferPool BufferPool
{
set
{
this.bufferPool = value;
}
}
public int ConnectionCount
{
get
{
return this.contextKeyManager.ConnectionCount;
}
}
public IContractHelper ContractHelper
{
set
{
this.contractHelper = value;
}
}
public ITcpStreamDispatcher Dispatcher
{
set
{
this.tcpStreamDispatcher = value;
}
}
public IEsbLogger EsbLogger
{
set
{
if (value != null)
{
this.esbLogger = value;
}
}
}
public int MaxMessageSize
{
set
{
this.maxMessageSize = value;
}
}
public int Port
{
get
{
return this.port;
}
set
{
this.port = value;
}
}
public int RecieveBuffSize
{
get
{
return this.recieveBuffSize;
}
set
{
this.recieveBuffSize = value;
}
}
}
//----------------------------------------------------
public class IocpTcp : ITcp, INet, ITcpEventList, ITcpClientsController, IOCPPackageHandler
{
public event CbSimpleInt ConnectionCountChanged;
public event CbSimpleStr DynamicMsgArrived;
public event CallBackForTcpMonitor ServiceCommitted;
public event CallBackForTcpMonitor ServiceDirectCommitted;
public event CbSimpleInt SomeOneConnected;
public event CallBackForTcpUser1 SomeOneDisConnected;
public event CallBackForTcpUser UserAction;
public IocpTcp()
{
this.iocpMgr = null;
this.messageDispatcher = null;
this.contextKeyMgr = new ContextKeyManager();
this.stateIsStop = true;
this.validateRequest = false;
this.curPort = 0x22b8;
}
private void ActivateUserActionEvent(int ConnectID, TcpUserAction action)
{
if (this.UserAction != null)
{
this.UserAction(ConnectID, action);
}
}
private void BindRequestToQueue(IAsyncResult ar)
{
try
{
ContextKey key1 = (ContextKey) ar.AsyncState;
key1.BytesRead = key1.NetStream.EndRead(ar);
if (!this.CheckData(key1))
{
return;
}
this.iocpMgr.Push(key1);
}
catch (Exception exception1)
{
exception1 = exception1;
}
}
private bool CheckData(ContextKey key)
{
int num1 = key.NetStream.GetHashCode();
if (this.stateIsStop)
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
return false;
}
if (key.BytesRead == 0)
{
this.DisposeOneConnection(num1, DisconnectedCause.LineOff);
return false;
}
if (key.BytesRead == 8)
{
string text1 = Encoding.BigEndianUnicode.GetString(key.Buffer, 0, 8);
this.DisposeOneConnection(num1, DisconnectedCause.LineOff);
return false;
}
return true;
}
private void DisposeOneConnection(int connectID)
{
this.contextKeyMgr.RemoveContextKey(connectID);
}
public void DisposeOneConnection(int connectID, DisconnectedCause cause)
{
this.DisposeOneConnection(connectID);
if (this.SomeOneDisConnected != null)
{
this.SomeOneDisConnected(connectID, cause);
}
this.ActivateUserActionEvent(connectID, TcpUserAction.Exit);
}
public NetAddinType GetProtocalType()
{
return NetAddinType.Tcp;
}
public void HandlerPackage(object package)
{
ContextKey key1 = package as ContextKey;
if (key1 != null)
{
int num1 = key1.NetStream.GetHashCode();
try
{
byte[] buffer1 = null;
ArrayList list1 = this.messageDispatcher.DealRequestMessage(key1.RequestData, out buffer1, ref key1.Validation);
if (this.validateRequest && key1.Validation.gotoCloseConnection)
{
this.DisposeOneConnection(num1, key1.Validation.cause);
}
else
{
key1.StreamState = NetStreamState.Writing;
if ((list1 != null) && (list1.Count != 0))
{
foreach (object obj1 in list1)
{
byte[] buffer2 = (byte[]) obj1;
key1.NetStream.Write(buffer2, 0, buffer2.Length);
if (this.ServiceCommitted != null)
{
RespondInformation information1 = new RespondInformation();
information1.ConnectID = num1;
information1.ServiceKey = this.messageDispatcher.GetServiceKey(buffer2);
information1.repondData = buffer2;
this.ServiceCommitted(information1);
}
this.ActivateUserActionEvent(num1, TcpUserAction.FunctionAccess);
}
}
if (key1.IsFirstMsg)
{
if ((list1 == null) || (list1.Count == 0))
{
key1.IsFirstMsg = true;
}
else
{
key1.IsFirstMsg = false;
}
}
key1.StreamState = NetStreamState.Idle;
key1.ResetBuffer(buffer1);
if (!this.stateIsStop)
{
this.RecieveDataFrom(key1);
}
else
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
}
}
}
catch (Exception exception1)
{
if (exception1 is IOException)
{
this.DisposeOneConnection(num1, DisconnectedCause.ServerStopped);
}
exception1 = exception1;
}
}
}
public void InitializeAll()
{
this.xtcpListener = new XTcpListener(this.curPort);
this.xtcpListener.TcpConnectionEstablished += new CBackUserLogon(this.xtcpListener_TcpConnectionEstablished);
this.xtcpListener.DynamicMsgArrived += new CbSimpleStr(this.PutoutDynamicMsg);
this.contextKeyMgr.StreamCountChanged += new CbSimpleInt(this.OnStreamCountChanged);
this.iocpMgr = new IOCPManager();
this.iocpMgr.Initialize(this, 50);
}
private void OnStreamCountChanged(int count)
{
if (this.ConnectionCountChanged != null)
{
this.ConnectionCountChanged(count);
}
}
private void PutoutDynamicMsg(string msg)
{
if (this.DynamicMsgArrived != null)
{
this.DynamicMsgArrived(msg);
}
}
private void RecieveDataFrom(ContextKey key)
{
try
{
key.StreamState = NetStreamState.Reading;
key.NetStream.BeginRead(key.Buffer, key.StartOffsetForRecieve, key.MaxRecieveCapacity, new AsyncCallback(this.BindRequestToQueue), key);
}
catch (Exception exception1)
{
exception1 = exception1;
}
}
public void SendData(int ConnectID, byte[] data)
{
this.SendData(ConnectID, data, 0, data.Length);
}
public void SendData(int ConnectID, byte[] data, int offset, int size)
{
if ((((data != null) && (data.Length != 0)) && ((offset >= 0) && (size >= 0))) && ((offset + size) <= data.Length))
{
ISafeNetworkStream stream1 = this.contextKeyMgr.GetNetStream(ConnectID);
if (stream1 != null)
{
stream1.Write(data, offset, size);
if (this.ServiceDirectCommitted != null)
{
RespondInformation information1 = new RespondInformation();
information1.ConnectID = ConnectID;
information1.ServiceKey = -1;
if ((offset == 0) && (size == data.Length))
{
information1.repondData = data;
}
else
{
information1.repondData = new byte[size];
for (int num1 = 0; num1 < size; num1++)
{
information1.repondData[num1] = data[offset + num1];
}
}
this.ServiceDirectCommitted(information1);
}
}
}
}
public void Start()
{
try
{
if (this.stateIsStop)
{
this.stateIsStop = false;
this.xtcpListener.Start();
this.iocpMgr.Start();
}
}
catch (Exception exception1)
{
throw exception1;
}
}
public void Stop()
{
if (!this.stateIsStop)
{
this.stateIsStop = true;
this.xtcpListener.Stop();
this.iocpMgr.Stop();
int num1 = 0;
while (!this.contextKeyMgr.IsAllStreamSafeToStop())
{
Thread.Sleep(200);
if (10 == num1++)
{
break;
}
}
this.contextKeyMgr.DisposeAllContextKey();
}
}
public bool SynRecieveFrom(int ConnectID, byte[] buffer, int offset, int size, out int readCount)
{
readCount = 0;
ISafeNetworkStream stream1 = this.contextKeyMgr.GetNetStream(ConnectID);
if (stream1 == null)
{
return false;
}
readCount = stream1.Read(buffer, offset, size);
return true;
}
public void UnitializeAll()
{
this.Stop();
this.xtcpListener.ExitListenThread();
this.ConnectionCountChanged = null;
this.DynamicMsgArrived = null;
this.ServiceCommitted = null;
this.SomeOneConnected = null;
this.SomeOneDisConnected = null;
this.UserAction = null;
this.ServiceDirectCommitted = null;
}
private void xtcpListener_TcpConnectionEstablished(NetworkStream stream)
{
ISafeNetworkStream stream1 = new SafeNetworkStream(stream);
ContextKey key1 = new ContextKey(stream1, 0x400);
key1.ResetBuffer(null);
this.contextKeyMgr.InsertContextKey(key1);
int num1 = key1.NetStream.GetHashCode();
if (this.SomeOneConnected != null)
{
this.SomeOneConnected(num1);
}
this.ActivateUserActionEvent(num1, TcpUserAction.Logon);
key1.IsFirstMsg = true;
this.RecieveDataFrom(key1);
}
public int ConnectionCount
{
get
{
return this.contextKeyMgr.ConnectionCount;
}
}
public IReqestStreamDispatcher Dispatcher
{
set
{
this.messageDispatcher = (ITcpReqStreamDispatcher) value;
}
}
public int Port
{
get
{
return this.curPort;
}
set
{
this.curPort = value;
}
}
public bool UserValidated
{
set
{
this.validateRequest = value;
}
}
private const int BufferSize = 0x400;
private ContextKeyManager contextKeyMgr;
private int curPort;
private IIOCPManager iocpMgr;
private const int MaxWorkThreadNum = 50;
private ITcpReqStreamDispatcher messageDispatcher;
private bool stateIsStop;
private bool validateRequest;
private IXTcpListener xtcpListener;
}