public void Pop_PoolEmpty_RetusnNull()
        {
            var pool = new SocketAsyncEventArgsPool(1);
            var args = pool.Pop();

            Assert.Null(args);
        }
예제 #2
0
        /// <summary>
        /// 异步发送消息
        /// </summary>
        /// <param name="sendQuere">发送消息体</param>
        private void Send(SendingQueue sendQuere)
        {
            try
            {
                mutex.WaitOne();
                if (m_sendPool.Count == 0)
                {
                    SocketAsyncEventArgs saea_send = new SocketAsyncEventArgs();
                    saea_send.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                    m_sendPool.Push(saea_send);
                }
                SocketAsyncEventArgs socketArgs = m_sendPool.Pop();
                mutex.ReleaseMutex();

                socketArgs.RemoteEndPoint = sendQuere.remoteEndPoint;
                socketArgs.SetBuffer(sendQuere.data, sendQuere.offset, sendQuere.length);

                if (listenSocket?.SendToAsync(socketArgs) == false)
                {
                    ProcessSend(socketArgs);
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
예제 #3
0
        /// <summary>
        /// 异步发送消息
        /// </summary>
        /// <param name="sendQuere">发送消息体</param>
        private void Send(SendingQueue sendQuere)
        {
            ConnectClient client;

            if (!connectClient.TryGetValue(sendQuere.connectId, out client))
            {
                return;
            }
            //如果发送池为空时,临时新建一个放入池中
            mutex.WaitOne();
            if (m_sendPool.Count == 0)
            {
                SocketAsyncEventArgs saea_send = new SocketAsyncEventArgs();
                saea_send.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                m_sendPool.Push(saea_send);
            }
            SocketAsyncEventArgs sendEventArgs = m_sendPool.Pop();

            mutex.ReleaseMutex();
            sendEventArgs.UserToken = sendQuere.connectId;
            sendEventArgs.SetBuffer(sendQuere.data, sendQuere.offset, sendQuere.length);
            try
            {
                if (!client.socket.SendAsync(sendEventArgs))
                {
                    ProcessSend(sendEventArgs);
                }
            }
            catch (ObjectDisposedException ex)
            {
                OnClose?.Invoke(sendQuere.connectId);
            }
            sendQuere = null;
        }
예제 #4
0
        /// <summary>
        /// 当异步连接完成时调用此方法
        /// </summary>
        /// <param name="e">操作对象</param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            connectId++;
            //把连接到的客户端信息添加到集合中
            ConnectClient connecttoken = new ConnectClient();

            connecttoken.socket = e.AcceptSocket;
            //从接受端重用池获取一个新的SocketAsyncEventArgs对象
            connecttoken.saea_receive              = m_receivePool.Pop();
            connecttoken.saea_receive.UserToken    = connectId;
            connecttoken.saea_receive.AcceptSocket = e.AcceptSocket;
            connectClient.TryAdd(connectId, connecttoken);
            clientList.TryAdd(connectId, e.AcceptSocket.RemoteEndPoint.ToString());
            //一旦客户机连接,就准备接收。
            if (!e.AcceptSocket.ReceiveAsync(connecttoken.saea_receive))
            {
                ProcessReceive(connecttoken.saea_receive);
            }
            //事件回调
            if (OnAccept != null)
            {
                OnAccept(connectId);
            }
            //接受第二连接的请求
            StartAccept(e);
        }
예제 #5
0
        private void ProcessAccept(object sender, SocketAsyncEventArgs e)
        {
            var readEventArgs = _SocketAsyncEventArgsPool.Pop();
            var ipEndPoint    = (IPEndPoint)e.AcceptSocket.RemoteEndPoint;
            var id            = $"{ipEndPoint.Address.ToString()}:{ipEndPoint.Port}";

            Console.WriteLine($"{id}已连接");

            var userToken = new AsyncUserToken
            {
                ID             = id,
                ConnectionTime = DateTime.Now,
                IPEndPoint     = ipEndPoint,
                Socket         = e.AcceptSocket
            };

            readEventArgs.UserToken = userToken;
            _UserTokens.TryAdd(id, userToken);

            if (!e.AcceptSocket.ReceiveAsync(readEventArgs))
            {
                ProcessReceive(readEventArgs);
            }

            StartAccept(e);
        }
        public void PopPush_Disposed_Exception()
        {
            var pool = new SocketAsyncEventArgsPool(64);

            // Populate the pool.
            for (int i = 0; i < 64; i++)
            {
                pool.Push(new SocketAsyncEventArgs());
            }

            // Remove a couple of the args.
            for (int i = 0; i < 32; i++)
            {
                pool.Pop();
            }

            pool.Dispose();

            Assert.Throws <ObjectDisposedException>(() => pool.Push(new SocketAsyncEventArgs()));
            Assert.Throws <ObjectDisposedException>(() => pool.Pop());
        }
예제 #7
0
        /// <summary>
        /// 处理已经完成连接请求的客户端SocketAsyncEventArgs对象
        /// </summary>
        /// <param name="acceptEventArgs"></param>
        private void TCPServerProcessAccept(SocketAsyncEventArgs acceptEventArgs)
        {
            if (acceptEventArgs.SocketError != SocketError.Success)
            {
                return;
            }

            try
            {
                /* 从SocketAsyncEventArgs池中获取一个SocketAsyncEventArgs */
                SocketAsyncEventArgs _AcceptSocketAsyncEventArgs = _TCPServerSocketAsyncEventArgsPool.Pop();

                if (_AcceptSocketAsyncEventArgs != null)
                {
                    _AcceptSocketAsyncEventArgs.UserToken = new SocketUserToKen(acceptEventArgs.AcceptSocket);

                    /* 在连接区增加客户端的IP结点信息 */
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        SynchronizationContext.SetSynchronizationContext(new
                                                                         DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                        SynchronizationContext.Current.Send(pl =>
                        {
                            TCPServerModel.ConnectionsInfo.Add(new TCPServerConnectionsInfo()
                            {
                                RemoteEndPoint = acceptEventArgs.AcceptSocket.RemoteEndPoint.ToString()
                            });
                        }, null);
                    });

                    bool _ReceivePending = acceptEventArgs.AcceptSocket.ReceiveAsync(_AcceptSocketAsyncEventArgs);

                    if (!_ReceivePending)
                    {
                        TCPServerProcessReceive(_AcceptSocketAsyncEventArgs);
                    }
                }
                else
                {
                    /* 拒绝客户端连接,因为已达到服务器允许的最大客户端连接数 */
                    acceptEventArgs.AcceptSocket.Close();
                }
            }
            catch
            {
                return;
            }

            TCPServerStartAcceptAsync(acceptEventArgs);   /* 开始等待来自下一个客户端的连接请求 */
        }
예제 #8
0
        private void DisposeAllSaeaObjects()
        {
            SocketAsyncEventArgs eventArgs;

            while (this._poolOfAcceptEventArgs.Count > 0)
            {
                eventArgs = _poolOfAcceptEventArgs.Pop();
                eventArgs.Dispose();
            }
            while (this._poolOfRecSendEventArgs.Count > 0)
            {
                eventArgs = _poolOfRecSendEventArgs.Pop();
                eventArgs.Dispose();
            }
        }
예제 #9
0
    // close connections and free up buffers when this GameObject is destroyed
    // when scene changes or game application terminated
    void OnDestroy()
    {
        shutDown = true;

        // stop listening for Unity Console LOG events
        Application.logMessageReceivedThreaded -= HandleLog;

        // clear buffers for pool of Asych Args
        while (m_readWritePool.Count > 0)
        {
            SocketAsyncEventArgs args = m_readWritePool.Pop();
            // process value

            args.SetBuffer(null, 0, 0);
        }

        activeClientSockets.ForEach(socket =>
        {
            // try to shutdown this active socket
            try
            {
                socket.Shutdown(SocketShutdown.Send);
            }
            // throws if client process has already closed
            catch (Exception) { }

            SafeCloseSocket(socket);
        });

        // close the listening socket
        SafeCloseSocket(listenSocket);

        Debug.Log("There are " + m_numConnectedSockets + " clients connected to the server");

        Debug.Log("server ended and sockets closed etc.");
    }
예제 #10
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            Interlocked.Increment(ref m_numConnectedSockets);
            _logger.LogInformation($"[当前连接数]:{_localEndPoint.Port} | {m_numConnectedSockets}");
            _logger.LogDebug($"leftPool: {m_readWritePool.Count}");

            try
            {
                // Get the socket for the accepted client connection and put it into the
                // ReadEventArg object user token
                SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
                if (readEventArgs == null)
                {
                    _logger.LogCritical($"Pop result is Null {m_readWritePool.Count}");
                    release(e);
                    return;
                }

                var token = readEventArgs.UserToken as AsyncUserToken;
                token.Socket     = e.AcceptSocket;
                token.MassgeTemp = null;
                token.Recived    = null;

                // 客户端请求不需要分配msgid
                if (m_isHttpServer)
                {
                    token.RequestId = $"{DateTime.Now.GetChinaTicks()}_{Guid.NewGuid().ToString().Replace("-", string.Empty)}";
                    _logger.LogDebug($"Accept {token.RequestId}");
                }

                // As soon as the client is connected, post a receive to the connection
                bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
                if (!willRaiseEvent)
                {
                    ProcessReceive(readEventArgs);
                }

                // Accept the next connection request
                StartAccept(e);
            }
            catch (Exception ex)
            {
                _logger.LogCritical(ex, "[ProcessAccept error]");
                release(e);
            }
        }
예제 #11
0
        /// <summary>
        /// 监听Socket接受处理
        /// </summary>
        /// <param name="e">SocketAsyncEventArg associated with the completed accept operation.</param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                Socket s = e.AcceptSocket;//和客户端关联的socket
                if (s.Connected)
                {
                    try
                    {
                        Interlocked.Increment(ref _clientCount);//原子操作加1
                        SocketAsyncEventArgs asyniar = _objectPool.Pop();
                        asyniar.UserToken = s;

                        //存储链接客户端
                        string cstr = s.RemoteEndPoint.ToString();
                        //创建空时间
                        Overall.lsocket.Add(cstr, s);
                        Overall.ListIP.Add(new OrtherResult()
                        {
                            IpAddressInfo = cstr, It_Is_Time = null, Difference_Time = "0"
                        });
                        //Overall.OverAllForm.comboBoxEdit1.Properties.Items.AddRange(new object[] { cstr });

                        //日志
                        Log4Debug(String.Format("Client {0} is Connected, Connected Count is {1}.", cstr, _clientCount), Outputoption.Info, Class: CurrentClassName, Method: MethodBase.GetCurrentMethod().Name);

                        if (!s.ReceiveAsync(asyniar))//投递接收请求
                        {
                            ProcessReceive(asyniar);
                        }
                    }
                    catch (SocketException ex)
                    {
                        Log4Debug(String.Format("Get from Client {0} Data is, Exception Information: {1} 。", s.RemoteEndPoint, ex.ToString()), Outputoption.Info, Class: CurrentClassName, Method: MethodBase.GetCurrentMethod().Name);
                        //TODO 异常处理
                    }
                    //投递下一个接受请求
                    StartAccept(e);
                }
            }
        }
예제 #12
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            connectId++;
            ConnectClient connecttoken = new ConnectClient();

            connecttoken.socket                    = e.AcceptSocket;
            connecttoken.saea_receive              = m_receivePool.Pop();
            connecttoken.saea_receive.UserToken    = connectId;
            connecttoken.saea_receive.AcceptSocket = e.AcceptSocket;
            connectClient.TryAdd(connectId, connecttoken);
            clientList.TryAdd(connectId, e.AcceptSocket.RemoteEndPoint.ToString());
            if (!e.AcceptSocket.ReceiveAsync(connecttoken.saea_receive))
            {
                ProcessReceive(connecttoken.saea_receive);
            }
            if (OnAccept != null)
            {
                OnAccept(connectId);
            }
            StartAccept(e);
        }
예제 #13
0
        private void Accept(object sender, SocketAsyncEventArgs e)
        {
            var ip     = e.AcceptSocket.RemoteEndPoint;
            var ioArgs = argsPool.Pop();

            ioArgs.AcceptSocket = e.AcceptSocket;
            var userData = new UserData()
            {
                ConnectTime    = DateTime.Now,
                RemoteEndPoint = ip,
                Socket         = e.AcceptSocket,
                ReceiveArgs    = ioArgs
            };

            e.AcceptSocket.ReceiveAsync(ioArgs);
            Console.WriteLine($"[{ip.ToString()} {userData.UserId.ToString()}] is connected");
            ioArgs.UserToken             = userData;
            ClientPool[userData.UserId]  = userData;
            AcceptEventArgs.AcceptSocket = null;
            ListenSocket.AcceptAsync(AcceptEventArgs);
        }
예제 #14
0
        internal void Send(SendingQueue sendQuere)
        {
            if (!socket.Connected)
            {
                return;
            }
            mutex.WaitOne();
            if (m_sendPool.Count == 0)
            {
                SocketAsyncEventArgs saea_send = new SocketAsyncEventArgs();
                saea_send.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                m_sendPool.Push(saea_send);
            }
            SocketAsyncEventArgs sendEventArgs = m_sendPool.Pop();

            mutex.ReleaseMutex();
            sendEventArgs.SetBuffer(sendQuere.data, sendQuere.offset, sendQuere.length);
            if (!socket.SendAsync(sendEventArgs))
            {
                ProcessSend(sendEventArgs);
            }
        }
예제 #15
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            Interlocked.Increment(ref m_numConnectedSockets);
            Console.WriteLine("Client connection accepted. There are {0} clients connected to the server", m_numConnectedSockets);

            // Get the socket for the accepted client connection and put it into the
            //ReadEventArg object user token
            SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();

            ((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;

            // As soon as the client is connected, post a receive to the connection
            bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);

            if (!willRaiseEvent)
            {
                ProcessReceive(readEventArgs);
            }

            // Accept the next connection request
            StartAccept(e);
        }
예제 #16
0
        private void OnNewClient(Socket cliSock, object token)
        {
            Interlocked.Increment(ref m_connectedCount);

            Console.WriteLine($"[{Thread.CurrentThread.ManagedThreadId}] A client connected. handle : {cliSock.Handle}, count : {m_connectedCount}");

            // 이벤트 풀에서 꺼내와 사용
            SocketAsyncEventArgs receiveArgs = m_receiveEventArgsPool.Pop();
            SocketAsyncEventArgs sendArgs    = m_sendEventArgsPool.Pop();

            // SocketAsyncEventArgs를 생성할 때 만들어두었던 UserToken를 콜백 메서드의 패러미터로 넣어줌.
            CustomUserToken userToken = null;

            if (m_sessionCreateCallback != null)
            {
                userToken = receiveArgs.UserToken as CustomUserToken;
                m_sessionCreateCallback(userToken);
            }

            // 클라이언트로부터 데이터를 수신 대기
            OnBeginReceive(cliSock, receiveArgs, sendArgs);
        }
예제 #17
0
        private static void HandleAsync(SocketAsyncEventArgs Args)
        {
            try
            {
                Interlocked.Increment(ref ConnectedAmount);

                var SingleSocketAsync = SocketPool.Pop();
                var Token             = (AsyncUserToken)SingleSocketAsync.UserToken;

                Token.Socket = Args.AcceptSocket;

                var Session = new Session(Interlocked.Increment(ref Counter), Token.Socket, Args);

                Sessions.Add(Session.Id, Session);

                if (!Args.AcceptSocket.ReceiveAsync(SingleSocketAsync))
                {
                    HandleReceive(SingleSocketAsync);
                }
            }
            catch { }
            finally { WaitForAsync(Args); }
        }
예제 #18
0
        /// <summary>
        /// 当异步连接完成时调用此方法
        /// </summary>
        /// <param name="e">操作对象</param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            //把连接到的客户端信息添加到集合中
            ConnectClient connecttoken = new ConnectClient();

            connecttoken.connectId = Guid.NewGuid();
            connecttoken.socket    = e.AcceptSocket;
            //从接受端重用池获取一个新的SocketAsyncEventArgs对象
            connecttoken.saea_receive = m_receivePool.Pop();
            connectClient.Add(connecttoken);
            //一旦客户机连接,就准备接收。
            if (!e.AcceptSocket.ReceiveAsync(connecttoken.saea_receive))
            {
                ProcessReceive(connecttoken.saea_receive);
            }
            //事件回调
            if (OnAccept != null)
            {
                OnAccept(connecttoken.connectId);
            }
            //接受第二连接的请求
            StartAccept(e);
        }
예제 #19
0
        /// <summary>
        /// 새로운 클라이언트가 접속 성공 했을 때 호출됩니다.
        /// AcceptAsync의 콜백 매소드에서 호출되며 여러 스레드에서 동시에 호출될 수 있기 때문에 공유자원에 접근할 때는 주의해야 합니다.
        /// </summary>
        /// <param name="client_socket"></param>
        /// <param name="token"></param>
        private void OnConnectedClient(System.Net.Sockets.Socket clientSocket, object token)
        {
            SocketAsyncEventArgs receiveArgs = _receiveEventAragePool.Pop();
            SocketAsyncEventArgs sendArgs    = _sendEventAragePool.Pop();

            _logger.Info(string.Format("[OnConnectedClient] _receiveEventAragePool: {0}, _sendEventAragePool: {1}", _receiveEventAragePool.Count, _sendEventAragePool.Count));


            // 소켓 옵션 설정.
            clientSocket.LingerState = new LingerOption(true, 10);
            clientSocket.NoDelay     = true;


            if (_authedClientSessions.Count == 0)
            {
                StartGameSession();
            }


            // 패킷 수신 시작
            ClientSession clientSession = receiveArgs.UserToken as ClientSession;

            BeginReceive(clientSocket, receiveArgs, sendArgs);
        }
예제 #20
0
        /// <summary>
        /// 异步发送消息
        /// </summary>
        /// <param name="sendQuere">发送消息体</param>
        private void Send(SendingQueue sendQuere)
        {
            ConnectClient client = connectClient.FirstOrDefault(P => P.connectId == sendQuere.connectId);

            if (client == null || client.socket.Connected == false)
            {
                return;
            }
            //如果发送池为空时,临时新建一个放入池中
            mutex.WaitOne();
            if (m_sendPool.Count == 0)
            {
                SocketAsyncEventArgs saea_send = new SocketAsyncEventArgs();
                saea_send.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed);
                m_sendPool.Push(saea_send);
            }
            SocketAsyncEventArgs sendEventArgs = m_sendPool.Pop();

            mutex.ReleaseMutex();
            sendEventArgs.UserToken = client.connectId;
            sendEventArgs.SetBuffer(sendQuere.data, sendQuere.offset, sendQuere.length);
            try
            {
                if (!client.socket.SendAsync(sendEventArgs))
                {
                    ProcessSend(sendEventArgs);
                }
            }
            catch (ObjectDisposedException ex)
            {
                if (OnClose != null)
                {
                    OnClose(client.connectId);
                }
            }
        }
예제 #21
0
 public void Send(DataPacketBase e, IPEndPoint ipe)
 {
     service.SendToAsync(socketPool.Pop());
 }
예제 #22
0
        static void Run(string[] args)
        {
            var performanceCountersCategoryName = "Microshaoft EasyPerformanceCounters Category";
            var enableCounters = MultiPerformanceCountersTypeFlags.ProcessCounter
                                 | MultiPerformanceCountersTypeFlags.ProcessedAverageTimerCounter
                                 | MultiPerformanceCountersTypeFlags.ProcessedCounter
                                 | MultiPerformanceCountersTypeFlags.ProcessedRateOfCountsPerSecondCounter
                                 | MultiPerformanceCountersTypeFlags.ProcessingCounter;
            var sendEncoding    = Encoding.Default;
            var receiveEncoding = Encoding.Default;

            //byte[] data = new byte[1024];
            string[]   a     = args[0].Split(new char[] { ':' });
            string     ip    = a[0];
            int        port  = int.Parse(a[1]);
            IPEndPoint ipep1 = new IPEndPoint(IPAddress.Parse(ip), port);

            Console.WriteLine("ipep1 {0}", ipep1.ToString());
            a    = args[1].Split(new char[] { ':' });
            ip   = a[0];
            port = int.Parse(a[1]);
            IPEndPoint ipep2 = new IPEndPoint(IPAddress.Parse(ip), port);

            Console.WriteLine("ipep2 {0}", ipep2.ToString());
            var    remoteAnyIPEP = new IPEndPoint(IPAddress.Any, 0);
            Socket socket1       = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket1.Bind(ipep1);
            SocketAsyncDataHandler <string> handler1 = new SocketAsyncDataHandler <string>(socket1, 1);
            var receiveSocketAsyncEventArgs1         = _socketAsyncEventArgsPool.Pop();

            _bufferManager.SetBuffer(receiveSocketAsyncEventArgs1);
            handler1.StartReceiveDataFrom
            (
                remoteAnyIPEP
                , receiveSocketAsyncEventArgs1
                , (x, y, z, w) =>
            {
                Console.WriteLine("次数: {0}", x.ReceivedCount);
                Console.WriteLine("字节: {0}", z.Length);
                EasyPerformanceCountersHelper <CommonPerformanceCountersContainer>
                .CountPerformance
                (
                    enableCounters
                    , performanceCountersCategoryName
                    , "Hander1::Received"
                    , null
                    , () =>
                {
                    var ss = receiveEncoding.GetString(z);
                    //Console.Write(s);
                    Console.WriteLine
                    (
                        "from {0} , to {1}, data {2}"
                        , x.WorkingSocket.LocalEndPoint
                        , w.RemoteEndPoint
                        , ss
                    );
                }
                    , null
                    , null
                    , null
                );
                return(false);
            }
                , (x, y, z) =>
            {
                Console.WriteLine(z.ToString());
                return(true);
            }
            );
            Socket socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            socket2.Bind(ipep2);
            SocketAsyncDataHandler <string> handler2 = new SocketAsyncDataHandler <string>(socket2, 2);
            var receiveSocketAsyncEventArgs2         = _socketAsyncEventArgsPool.Pop();

            _bufferManager.SetBuffer(receiveSocketAsyncEventArgs2);
            handler2.StartReceiveDataFrom
            (
                remoteAnyIPEP
                , receiveSocketAsyncEventArgs2
                , (x, y, z, w) =>
            {
                Console.WriteLine("次数: {0}", x.ReceivedCount);
                Console.WriteLine("字节: {0}", z.Length);
                EasyPerformanceCountersHelper <CommonPerformanceCountersContainer>
                .CountPerformance
                (
                    enableCounters
                    , performanceCountersCategoryName
                    , "Hander2::Received"
                    , null
                    , () =>
                {
                    var ss = receiveEncoding.GetString(z);
                    //Console.Write(s);
                    Console.WriteLine
                    (
                        "from {0} , to {1}, data {2}"
                        , x.WorkingSocket.LocalEndPoint
                        , w.RemoteEndPoint
                        , ss
                    );
                }
                    , null
                    , null
                    , null
                );
                return(false);
            }
                , (x, y, z) =>
            {
                Console.WriteLine(z.ToString());
                return(true);
            }
            );
            string s = string.Empty;

            Console.WriteLine("Send ...");
            while ((s = Console.ReadLine().ToLower()) != "q")
            {
                var buffer = sendEncoding.GetBytes(s);
                Parallel.For
                (
                    0
                    , 1000
                    , new ParallelOptions()
                {
                    MaxDegreeOfParallelism = 1 // Environment.ProcessorCount
                                               //, TaskScheduler = null
                }
                    , i =>
                {
                    Thread.Sleep(5);
                    EasyPerformanceCountersHelper <CommonPerformanceCountersContainer>
                    .CountPerformance
                    (
                        enableCounters
                        , performanceCountersCategoryName
                        , "Hander1::Sended"
                        , null
                        , () =>
                    {
                        handler1.SendDataToSync(buffer, ipep2);
                    }
                        , null
                        , null
                        , null
                    );
                    EasyPerformanceCountersHelper <CommonPerformanceCountersContainer>
                    .CountPerformance
                    (
                        enableCounters
                        , performanceCountersCategoryName
                        , "Hander2::Sended"
                        , null
                        , () =>
                    {
                        handler2.SendDataToSync(buffer, ipep1);
                    }
                        , null
                        , null
                        , null
                    );
                }
                );
            }
            var e = handler1.ReceiveSocketAsyncEventArgs;

            //_bufferManager.FreeBuffer(e);
            _socketAsyncEventArgsPool.Push(e);
            e = handler2.ReceiveSocketAsyncEventArgs;
            //_bufferManager.FreeBuffer(e);
            _socketAsyncEventArgsPool.Push(e);
            handler1.DestoryWorkingSocket();
            handler2.DestoryWorkingSocket();
            Console.WriteLine("Send quit");
        }
예제 #23
0
        protected override void OnSocketAccepted(ISocketListener listener, Socket socket)
        {
            if (socket == null)
            {
                return;
            }

            try
            {
                var config = appServer.config;

                // 소켓 옵션 설정.
                if (config.sendTimeOut > 0)
                {
                    socket.SendTimeout = config.sendTimeOut;
                }

                if (config.sendBufferSize > 0)
                {
                    socket.SendBufferSize = config.sendBufferSize;
                }

                if (config.receiveBufferSize > 0)
                {
                    socket.ReceiveBufferSize = config.receiveBufferSize;
                }

                //TODO @jeongtae.lee : 지원 여부 알아보기 (IOControl와 함께)
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, _keepAliveOptionValue);
                socket.NoDelay     = true;                      // Nagle 알고리즘 적용 여부(TRUE : 적용하지 않음). 패킷을 모아서 보낼 것인지 설정하는 옵션 즉각적인 응답이 중요한 곳에서는 사용하지 않는다)
                socket.LingerState = new LingerOption(true, 0); // 두번째 인자가 0이면 close 호출 시 버퍼에 남아있는 모든 송수신 데이터를 버리고 즉시 종료한다.

                var socketEvent = _recvSocketEventPool.Pop();
                if (socketEvent == null)
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Max connection number {0} was reached.", config.maxConnection);
                    }

                    return;
                }

                var sessionId = appServer.CreateSessionId();
                if (string.IsNullOrEmpty(sessionId))
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Failed to create session ID.");
                    }

                    return;
                }

                var appSession = appServer.CreateAppSession();
                if (appSession == null)
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Failed to create AppSession");
                    }

                    return;
                }

                var socketSession = new AsyncSocketSession(socketEvent);
                if (!socketSession.Initialize(appSession, socket))
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Failed to initialize AsyncSocketSession");
                    }

                    return;
                }

                if (!appSession.Initialize(sessionId, socketSession))
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Failed to initialize AppSession");
                    }

                    return;
                }

                if (!appServer.AddSession(appSession))
                {
                    this.AsyncRun(socket.Close);

                    if (logger.IsErrorEnabled)
                    {
                        logger.ErrorFormat("Failed to add app session to app server.");
                    }

                    return;
                }

                appServer.AsyncRun(socketSession.Start);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
예제 #24
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            AsyncUserToken token;

            Interlocked.Increment(ref m_numConnectedSockets);
            Debug.WriteLine(string.Format("客户端连接请求被接受. 有 {0} 个客户端连接到服务器",
                                          m_numConnectedSockets.ToString()));
            SocketAsyncEventArgs readEventArg;

            // 获得已经接受的客户端连接Socket并把它放到ReadEventArg对象的user token中
            lock (m_readPool)
            {
                readEventArg = m_readPool.Pop();
            }

            token = (AsyncUserToken)readEventArg.UserToken;

            // 把它放到ReadEventArg对象的user token中
            token.Socket = e.AcceptSocket;

            // 获得一个新的Guid 32位 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            token.ConnectionId = Guid.NewGuid().ToString("N");

            lock (((ICollection)this.m_tokens).SyncRoot)
            {
                this.m_tokens.Add(token.ConnectionId, token);// 添加到集合中
            }

            EventHandler <AsyncUserToken> handler = OnClientConnect;

            // 如果订户事件将为空(null)
            if (handler != null)
            {
                handler(this, token);// 抛出客户端连接事件
            }

            try
            {
                // 客户端一连接上就抛出一个接收委托给连接的Socket开始接收数据
                bool willRaiseEvent = token.Socket.ReceiveAsync(readEventArg);
                if (!willRaiseEvent)
                {
                    ProcessReceive(readEventArg);
                }
            }
            catch (ObjectDisposedException)
            {
                RaiseDisconnectedEvent(token);
            }
            catch (SocketException socketException)
            {
                if (socketException.ErrorCode == (int)SocketError.ConnectionReset) // 10054一个建立的连接被远程主机强行关闭
                {
                    RaiseDisconnectedEvent(token);                                 // 引发断开连接事件
                }
                else
                {
                    RaiseErrorEvent(token, new AsyncSocketException("在SocketAsyncEventArgs对象上执行异步接收数据操作时发生SocketException异常", socketException));
                }
            }
            catch (Exception exception_debug)
            {
                Debug.WriteLine("调试:" + exception_debug.Message);
                throw exception_debug;
            }
            finally
            {
                // 接受下一个连接请求
                StartAccept(e);
            }
        }
예제 #25
0
        public void Send(string connectionId, byte[] buffer)
        {
            AsyncUserToken token;

            //SocketAsyncEventArgs token;

            //if (buffer.Length <= m_receiveSendBufferSize)
            //{
            //    throw new ArgumentException("数据包长度超过缓冲区大小", "buffer");
            //}

            lock (((ICollection)this.m_tokens).SyncRoot)
            {
                if (!this.m_tokens.TryGetValue(connectionId, out token))
                {
                    throw new AsyncSocketException(string.Format("客户端:{0}已经关闭或者未连接", connectionId), AsyncSocketErrorCode.ClientSocketNoExist);

                    //return;
                }
            }
            SocketAsyncEventArgs writeEventArgs;

            lock (m_writePool)
            {
                writeEventArgs = m_writePool.Pop();// 分配一个写SocketAsyncEventArgs对象
            }
            writeEventArgs.UserToken = token;
            if (buffer.Length <= m_BufferSize)
            {
                Array.Copy(buffer, 0, writeEventArgs.Buffer, writeEventArgs.Offset, buffer.Length);
                writeEventArgs.SetBuffer(writeEventArgs.Buffer, writeEventArgs.Offset, buffer.Length);
            }
            else
            {
                lock (m_bufferLock)
                {
                    m_bufferManager.FreeBuffer(writeEventArgs);
                }
                writeEventArgs.SetBuffer(buffer, 0, buffer.Length);
            }

            //writeEventArgs.SetBuffer(buffer, 0, buffer.Length);
            try
            {
                // 异步发送数据
                bool willRaiseEvent = token.Socket.SendAsync(writeEventArgs);
                if (!willRaiseEvent)
                {
                    ProcessSend(writeEventArgs);
                }
            }
            catch (ObjectDisposedException)
            {
                RaiseDisconnectedEvent(token);
            }
            catch (SocketException socketException)
            {
                if (socketException.ErrorCode == (int)SocketError.ConnectionReset) //10054一个建立的连接被远程主机强行关闭
                {
                    RaiseDisconnectedEvent(token);                                 //引发断开连接事件
                }
                else
                {
                    RaiseErrorEvent(token, new AsyncSocketException("在SocketAsyncEventArgs对象上执行异步发送数据操作时发生SocketException异常", socketException));;
                }
            }
            catch (Exception exception_debug)
            {
                Debug.WriteLine("调试:" + exception_debug.Message);
                throw exception_debug;
            }
        }