Esempio n. 1
0
        /// <summary>
        /// 开始监听
        /// </summary>
        /// <param name="e">接收数据</param>
        /// <param name="server">服务端</param>
        public static void Listener <TPackageParse>(AsyncSocketTokenEventArgs e, AsyncSocketServer server) where TPackageParse : INetPackageParse, new()
        {
            try {
                IList <INetPackage> packages = Singleton <TPackageParse> .Instance().Parse(e, AsyncSocketServerReceive.LittleEndian, AsyncSocketServerReceive.MaxPackageSize);

                if (packages == null)
                {
                    server.Disconnect(e.ConnectionID);
                    if (AsyncSocketServerReceive.ErrorMsg != null)
                    {
                        AsyncSocketServerReceive.ErrorMsg.BeginInvoke("超出最大包大小:" + AsyncSocketServerReceive.MaxPackageSize.ToString() + ",连接被强行断开!", null, null);
                    }
                }
                else
                {
                    foreach (INetPackage package in packages)
                    {
                        if (package != null)
                        {
                            if (serverEvents.ContainsKey(package.Command))
                            {
                                serverEvents[package.Command].Process(package, e.ConnectionID, server);
                            }
                            else if (AsyncSocketServerReceive.ErrorMsg != null)
                            {
                                AsyncSocketServerReceive.ErrorMsg.BeginInvoke(package.Command.ToString() + "指令不存在!", null, null);
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                if (AsyncSocketServerReceive.ErrorMsg != null)
                {
                    AsyncSocketServerReceive.ErrorMsg.BeginInvoke(ex.Message, null, null);
                }
            }
        }
        /// <summary>
        /// 将接收到的字节转成数据包
        /// </summary>
        /// <param name="packs">数据包列表</param>
        /// <param name="e">接收数据</param>
        /// <param name="littleEndian">小端</param>
        /// <param name="maxPackageSize">最大包大小</param>
        /// <returns>数据包数 -1为非法数据包</returns>
        public IList <INetPackage> Parse(AsyncSocketTokenEventArgs e, bool littleEndian = true, int maxPackageSize = 10240)
        {
            //lock (((ICollection)lockers).SyncRoot) { }
            if (!lockers.ContainsKey(e.ConnectionID))
            {
                lockers[e.ConnectionID] = new object();
            }

            lock (lockers[e.ConnectionID]) {
                if (cache.ContainsKey(e.ConnectionID))
                {
                    cache[e.ConnectionID] = EndianHelper.UnionBytes(cache[e.ConnectionID], e.ReceivedBytes);
                }
                else
                {
                    cache[e.ConnectionID] = EndianHelper.UnionBytes(null, e.ReceivedBytes);
                }

                byte[] data  = cache[e.ConnectionID];
                int    count = data.Length;
                if (count <= 4)
                {
                    return(new List <INetPackage>());
                }
                if (count > maxPackageSize)
                {
                    return(null);
                }

                IList <INetPackage> packs = new List <INetPackage>();
                while (count > 4)
                {
                    using (System.IO.MemoryStream stream = new System.IO.MemoryStream(data)) {
                        StreamReader reader = new StreamReader(stream, littleEndian);
                        int          length = reader.ReadInt();
                        if (length > 0 && count >= length + 4)
                        {
                            INetPackage package = new SerializePackage();

                            byte[] result = new byte[length];
                            System.IO.MemoryStream resultStream = new System.IO.MemoryStream(result);
                            stream.Position = 4;
                            stream.Read(result, 0, length);
                            package.Stream  = new StreamReader(resultStream, littleEndian);
                            package.Command = package.Stream.ReadInt();

                            data            = new byte[count - length - 4];
                            stream.Position = length + 4;
                            stream.Read(data, 0, count - length - 4);
                            cache[e.ConnectionID] = data;

                            packs.Add(package);
                            count = count - length - 4;
                        }
                        else
                        {
                            if (length < 0)
                            {
                                cache[e.ConnectionID] = null;
                            }
                            return(packs);
                        }
                    }
                }
                return(packs);
            }
        }
        /// <summary>
        /// 连接远程服务器
        /// </summary>
        /// <param name="remoteEndPoint">远程服务器</param>
        /// <param name="useIOCP">是否使用IOCP</param>
        public void Connect(IPEndPoint remoteEndPoint, bool useIOCP = true)
        {
            if (IsConnected)
            {
                return;
            }
            this.remoteEndPoint = remoteEndPoint;
            this.useIOCP        = useIOCP;
            this.CheckDisposed();

            if (this.clientSocket != null)
            {
                if (IsConnected)
                {
                    this.clientSocket.Shutdown(SocketShutdown.Both);
                    this.clientSocket.Close();
                }
                this.clientSocket = null;
            }

            this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType);
            this.clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            this.clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
#if !MONO
            if (KeepAlive)
            {
                this.clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

                byte[] array = new byte[Marshal.SizeOf(first) * 3];
                BitConverter.GetBytes((uint)1).CopyTo(array, 0);
                BitConverter.GetBytes(first).CopyTo(array, Marshal.SizeOf(first));
                BitConverter.GetBytes(interval).CopyTo(array, (int)(Marshal.SizeOf(first) * 2));
                this.clientSocket.IOControl(IOControlCode.KeepAliveValues, array, null);
            }
#endif
            this.clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, NoDelay);
            this.clientSocket.NoDelay        = NoDelay;
            this.clientSocket.SendTimeout    = SendTimeout;
            this.clientSocket.ReceiveTimeout = ReceiveTimeout;
            try {
                this.clientSocket.UseOnlyOverlappedIO = useIOCP;
                this.token = new AsyncSocketTokenEventArgs(this.clientSocket);
                this.token.ConnectionID = Guid.NewGuid();
                this.token.SetBuffer(this.token.ReadEventArgs.Buffer, this.token.ReadEventArgs.Offset);

                this.clientSocket.BeginConnect(remoteEndPoint, new AsyncCallback(this.ProcessConnect), this.clientSocket);

                if (debug)
                {
                    Debug.Write("客户端连接成功...");
                }
            } catch (ObjectDisposedException e) {
                if (debug)
                {
                    Debug.Write(string.Format(errorFormat, "AsyncSocketClient.Connect", e.Source, e.Message, e.StackTrace, e.ToString()));
                }
                IsConnected = false;
                this.RaiseEvent(this.Disconnected, new AsyncSocketTokenEventArgs(this.clientSocket));
            } catch (SocketException e) {
                if (debug)
                {
                    Debug.Write(string.Format(errorFormat, "AsyncSocketClient.Connect", e.Source, e.Message, e.StackTrace, e.ToString()));
                }
                if (e.ErrorCode == (int)SocketError.ConnectionReset || e.ErrorCode == (int)SocketError.ConnectionRefused || e.ErrorCode == (int)SocketError.TimedOut || e.ErrorCode < -1)
                {
                    IsConnected = false;
                    this.RaiseEvent(this.Disconnected, this.token);
                }

                this.OnError(this.token.Socket, new AsyncSocketErrorEventArgs(e.Message, e, AsyncSocketErrorCode.ClientConnectException));
            } catch (Exception e) {
                if (debug)
                {
                    Debug.Write(string.Format(errorFormat, "AsyncSocketClient.Connect", e.Source, e.Message, e.StackTrace, e.ToString()));
                }
                IsConnected = false;
                this.RaiseEvent(this.Disconnected, this.token);
                this.OnError(this.token.Socket, new AsyncSocketErrorEventArgs(e.Message, e, AsyncSocketErrorCode.ClientConnectException));
            }
        }
        /// <summary>
        /// 唤起事件
        /// </summary>
        /// <param name="eventHandler">EventHandler.</param>
        /// <param name="eventArgs">AsyncSocketTokenEventArgs.</param>
        private void RaiseEvent(EventHandler <AsyncSocketTokenEventArgs> eventHandler, AsyncSocketTokenEventArgs eventArgs)
        {
            // Copy a reference to the delegate field now into a temporary field for thread safety
            EventHandler <AsyncSocketTokenEventArgs> temp = Interlocked.CompareExchange(ref eventHandler, null, null);

            if (temp != null)
            {
                temp(this, eventArgs);
            }
        }
Esempio n. 5
0
 private static void server_DataReceived(object sender, AsyncSocketTokenEventArgs e)
 {
     AsyncSocketServerReceive.Listener <StreamPackageParse>(e, server); //服务端接收监听
 }
Esempio n. 6
0
        /// <summary>
        /// 将接收到的字节转成数据包
        /// </summary>
        /// <param name="packs">数据包列表</param>
        /// <param name="e">接收数据</param>
        /// <param name="littleEndian">小端</param>
        /// <param name="maxPackageSize">最大包大小</param>
        /// <returns>数据包数 -1为非法数据包</returns>
        public IList <INetPackage> Parse(AsyncSocketTokenEventArgs e, bool littleEndian = true, int maxPackageSize = 10240)
        {
            //lock (((ICollection)lockers).SyncRoot) {}
            if (!lockers.ContainsKey(e.ConnectionID))
            {
                lockers[e.ConnectionID] = new object();
            }

            lock (lockers[e.ConnectionID]) {
                if (cache.ContainsKey(e.ConnectionID))
                {
                    cache[e.ConnectionID] = EndianHelper.UnionBytes(cache[e.ConnectionID], e.ReceivedBytes);
                }
                else
                {
                    cache[e.ConnectionID] = EndianHelper.UnionBytes(null, e.ReceivedBytes);
                }

                byte[] data  = cache[e.ConnectionID];
                int    count = data.Length;
                if (count <= 4)
                {
                    return(new List <INetPackage>());
                }
                if (count > maxPackageSize)
                {
                    return(null);
                }

                IList <INetPackage> packs = new List <INetPackage>();
                while (count > 4)
                {
                    byte[] lenBytes = new byte[4];
                    Buffer.BlockCopy(data, 0, lenBytes, 0, 4);

                    StructPackageLength lenPack = EndianHelper.BytesToStruct <StructPackageLength>(lenBytes);
                    int length = lenPack.Size;
                    if (length > 0 && count >= length + 14)
                    {
                        byte[] bytes = new byte[10240 + 10 + 4];
                        Buffer.BlockCopy(data, 0, bytes, 0, length + 14);
                        StructPackageData packData = EndianHelper.BytesToStruct <StructPackageData>(bytes);

                        byte[] resultBytes = new byte[packData.Size];
                        Buffer.BlockCopy(packData.Bytes, 0, resultBytes, 0, packData.Size);
                        System.IO.MemoryStream resultStream = new System.IO.MemoryStream(resultBytes);

                        StructPackage pack = new StructPackage();
                        pack.Command = packData.Command;
                        pack.Stream  = new StreamReader(resultStream, littleEndian);
                        packs.Add(pack);

                        byte[] data2 = new byte[count - length - 14];
                        Buffer.BlockCopy(data, length + 14, data2, 0, count - length - 14);
                        count = count - length - 14;
                        data  = data2;
                        cache[e.ConnectionID] = data;
                    }
                    else
                    {
                        if (length < 0)
                        {
                            cache[e.ConnectionID] = null;
                        }
                        return(packs);
                    }
                }
                return(packs);
            }
        }
Esempio n. 7
0
 private static void server_Disconnected(object sender, AsyncSocketTokenEventArgs e)
 {
     ServerMsg(e.ConnectionID.ToString() + " 断开连接!");
     AsyncSocketServerReceive.RemoveListener <StreamPackageParse>(e.ConnectionID); //服务端断开连接时,清理包缓存数据
 }
Esempio n. 8
0
 private static void server_Connected(object sender, AsyncSocketTokenEventArgs e)
 {
     ServerMsg(e.ConnectionID.ToString() + " 连接成功!");
 }
Esempio n. 9
0
 private static void client_DataReceived(object sender, AsyncSocketTokenEventArgs e)
 {
     AsyncSocketClientReceive.Listener <StreamPackageParse>(e, client); //客户端接收监听 使用StreamPackageParse
 }
Esempio n. 10
0
 private static void client_Disconnected(object sender, AsyncSocketTokenEventArgs e)
 {
     AsyncSocketClientReceive.RemoveListener <StreamPackageParse>(e.ConnectionID); //客户端断开连接时,清理包缓存数据
 }
Esempio n. 11
0
        private static void client_Connected(object sender, AsyncSocketTokenEventArgs e)
        {
            ClientMsg("连接服务器成功,向服务器发送登录消息!");

            sendLoginMessage();
        }