【转载】支持漫游用户和跨区域功能请求

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;
    }

原文地址:https://www.cnblogs.com/fx2008/p/2252510.html