//-----------------------------------
#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 Memberspublic 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; }