Esempio n. 1
0
 /// <summary>
 /// 监听客户端连接的异步回调
 /// </summary>
 /// <param name="ar"></param>
 private void Listen_Callback(IAsyncResult ar)
 {
     try
     {
         TcpListener listener = (TcpListener)ar.AsyncState;
         if (null != listener)
         {
             Socket      ss = listener.EndAcceptSocket(ar);
             StateObject so = new StateObject();
             so.socket = ss;
             so.point  = ss.RemoteEndPoint as IPEndPoint;
             ss.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), so);
             lock (_clients)
             {
                 _clients.Add(so);
             }
             if (null != OnConnected)
             {
                 var aud = new AsyncUserDataEvent();
                 aud.Data = _bufferPool.Get();
                 aud.Data.SetDataEvent(so, 0);
                 OnConnected(this, aud);
             }
             HandleOnMessage(Environment.NewLine + Now + "Client [" + so.point.Address.ToString() + ":" + so.point.Port + "] connected.");
             _listener.BeginAcceptSocket(new AsyncCallback(Listen_Callback), _listener);
         }
     }
     catch (ObjectDisposedException e)
     {
         if (!IsStop)
         {
             HandleOnMessage(Now + "Listen_Callback error: " + e.Message + Environment.NewLine + e.StackTrace);
         }
     }
 }
Esempio n. 2
0
        /// <summary>
        /// 读取数据的回调
        /// </summary>
        /// <param name="ar"></param>
        private void Read_Callback(IAsyncResult ar)
        {
            try
            {
                StateObject so = (StateObject)ar.AsyncState;
                lock (so)
                {
                    if (null == so)
                    {
                        return;
                    }
                    Socket s = so.socket;

                    int read = s.EndReceive(ar);
                    if (read > 0)
                    {
                        if (null == so.Received)
                        {
                            so.Received = new byte[read];
                            so.length   = read;
                        }
                        else
                        {
                            so.length  += read;
                            so.Received = Wbs.Utilities.CustomConvert.expand(so.Received, so.length);
                        }
                        Buffer.BlockCopy(so.buffer, 0, so.Received, so.length - read, read);
                        s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, SocketFlags.None, new AsyncCallback(Read_Callback), so);
                        if (so.length >= so.Received[0])
                        {
                            // 加入队列并等待处理
                            if (null != OnReceivedData)
                            {
                                var aud = new AsyncUserDataEvent();
                                aud.Data = _bufferPool.Get();
                                aud.Data.SetDataEvent(so, 2);
                                OnReceivedData(this, aud);
                            }
                            so.ClearReceived();
                        }
                    }
                    else
                    {
                        HandleOnMessage(string.Format("{0}Iridium server {1}:{2} disconnected.", Now, so.point.Address.ToString(), so.point.Port));
                        if (null != OnDisconnected)
                        {
                            var aud = new AsyncUserDataEvent();
                            aud.Data = _bufferPool.Get();
                            aud.Data.SetDataEvent(so, 1);
                            OnDisconnected(this, aud);
                        }
                        //so.socket.Shutdown(SocketShutdown.Both);
                        //so.socket.Close();
                    }
                }
            }
            catch (Exception e)
            { HandleOnMessage(Now + "Read_Callback error: " + e.Message + Environment.NewLine + e.StackTrace); }
        }
Esempio n. 3
0
        /// <summary>
        /// 关闭一个连接。
        /// </summary>
        /// <param name="e"></param>
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            var aut = e.UserToken as AsyncUserToken;

            // socket 已经关闭过了,直接返回
            if (null == aut.Socket)
            {
                return;
            }

            // 通知客户端断开事件
            if (null != OnDisconnected)
            {
                var aude = new AsyncUserDataEvent();
                aude.Data = _bufferPool.Get();
                aude.Data.SetDataEvent(e, false);
                aude.Data.PackageType = AsyncDataPackageType.TCP;
                OnDisconnected(this, aude);
            }

            // 关闭 socket 关联的发送操作。
            try
            {
                aut.Socket.Shutdown(SocketShutdown.Both);
            }
            // 屏蔽当 socket 已经关闭的异常。
            catch (Exception) { }
            aut.Socket.Close();
            aut.Socket = null;

            // 释放一个等待队列信号,以便让在连接 accept 队列中等待处理的新连接得到处理。
            m_maxNumberAcceptedClients.Release();

            // 将该连接节点的 SocketAsyncEventArgs 回收到 SocketAsyncEventArgsPool 池中等待继续使用。
            saea_readWritePool.Push(e);

            // 从链接队列中移除节点
            lock (_clients)
            {
                _clients.Remove(aut);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// 客户端连接成功的处理过程。
        /// 客户端的基本信息在此绑定到某一个 SocketAsyncEventArgs 中。
        /// </summary>
        /// <param name="e"></param>
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                // 从 SocketAsyncEventArgsPool 池中取出一个空节点来保存新连接进来的客户端。
                SocketAsyncEventArgs readEventArgs = saea_readWritePool.Pop();
                // 将客户端信息附加到用户信息上。
                var aut = readEventArgs.UserToken as AsyncUserToken;
                aut.Socket = e.AcceptSocket;
                aut.RecycleData();

                // 将新入的链接加入队列
                lock (_clients)
                {
                    _clients.Add(aut);
                }

                // 通知处理客户端连接事件
                if (null != OnConnected)
                {
                    var aude = new AsyncUserDataEvent();
                    aude.Data = _bufferPool.Get();
                    aude.Data.SetDataEvent(readEventArgs, true);
                    aude.Data.PackageType = AsyncDataPackageType.TCP;
                    OnConnected(this, aude);
                }

                // 向新连接进来的客户端投递 receive 操作。
                bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
                // 如果客户端此时发送数据则需要立即处理。
                if (!willRaiseEvent)
                {
                    ProcessReceive(readEventArgs);
                }

                // 继续等待新的客户端连接。
                StartAccept(e);
            }
        }
Esempio n. 5
0
 /// <summary>
 /// 接收客户端的数据或客户端的断开信息。
 /// </summary>
 /// <param name="e"></param>
 private void ProcessReceive(SocketAsyncEventArgs e)
 {
     if (null == (e.UserToken as AsyncUserToken).Socket)
     {
         return;
     }
     // 如果 BytesTransferred 不为 0 且没有发送 SocketError,则说明收到客户端发送的信息。
     if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
     {
         var token = e.UserToken as AsyncUserToken;
         lock (token)
         {
             token.ReceiveData(e.BytesTransferred, e.Buffer, e.Offset);
             if (token.Length >= token.Buffer[0])
             {
                 // 如果收到的是完整的包则直接发给前台处理
                 if (null != OnReceivedData)
                 {
                     var aude = new AsyncUserDataEvent();
                     aude.Data = _bufferPool.Get();
                     aude.Data.SetDataEvent(token);
                     aude.Data.PackageType = AsyncDataPackageType.TCP;
                     OnReceivedData(this, aude);
                     // 消息接收完毕之后清空接收缓冲区
                     token.RecycleData();
                 }
             }
         }
         // 锁定socket?
         //lock (token.Socket)
         //{
         //    lock (_TCP_Buffer_Received)// 锁定缓冲区
         //    {
         //        //var token = e.UserToken as AsyncUserToken;
         //        var socket = token.SocketHandle;
         //        // 如果缓冲区中有这个socket的数据,说明之前的数据收到的不完整,需要再组包
         //        if (_TCP_Buffer_Received.ContainsKey(socket))
         //        {
         //            // 组包
         //            var data = _TCP_Buffer_Received[socket];
         //            data.ResizeData(e);
         //            if (data.Buffer.Length >= data.Buffer[0])
         //            {
         //                // 包长度足够之后从暂存缓存中移除节点
         //                _TCP_Buffer_Received.Remove(socket);
         //                // 发送消息
         //                OnReceivedData(this, new AsyncUserDataEvent() { Data = data });
         //            }
         //        }
         //        else
         //        {
         //            if (e.BytesTransferred >= e.Buffer[e.Offset])
         //            {
         //                // 如果收到的是完整的包则直接发给前台处理
         //                if (null != OnReceivedData)
         //                {
         //                    var aude = new AsyncUserDataEvent();
         //                    aude.Data = _bufferPool.Get();
         //                    aude.Data.SetDataEvent(e, 0);
         //                    aude.Data.PackageType = AsyncDataPackageType.TCP;
         //                    OnReceivedData(this, aude);
         //                }
         //            }
         //            else
         //            {
         //                //var aude = new AsyncUserDataEvent();
         //                var data = _bufferPool.Get();
         //                data.SetDataEvent(e, 0);
         //                data.PackageType = AsyncDataPackageType.TCP;
         //                _TCP_Buffer_Received.Add(socket, data);
         //            }
         //        }
         //    }
         //}
         //回传收到的信息。
         //e.SetBuffer(e.Offset, e.BytesTransferred);
         //e.SetBuffer(0, 0);
         // 数据接收完毕之后重新在连接上投递 receive 操作,如此循环,就可以不断的接收到客户端发送的数据。
         bool willRaiseEvent = (e.UserToken as AsyncUserToken).Socket.ReceiveAsync(e);//token.Socket.SendAsync(e);
         if (!willRaiseEvent)
         {
             ProcessReceive(e);
         }
     }
     else
     {
         CloseClientSocket(e);
     }
 }
Esempio n. 6
0
        /// <summary>
        /// 处理UDP接受的线程
        /// </summary>
        private void handleUdpReceive()
        {
            int len = 0;

            byte[] buffer = new byte[1024];
            while (!stoped)
            {
                try {
                    if (null != udpSocket)
                    {
                        len = 0;
                        EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
                        len = udpSocket.ReceiveFrom(buffer, ref clientEP);

                        lock (udpSocket)
                        {
                            var ip    = (clientEP as IPEndPoint).Address.ToString();
                            var port  = (clientEP as IPEndPoint).Port;
                            var token = ip + ":" + port.ToString();
                            //AsyncUserToken token = new AsyncUserToken();
                            //token.IP = (clientEP as IPEndPoint).Address.ToString();
                            //token.Port = (clientEP as IPEndPoint).Port;
                            lock (_UDP_Buffer_Received)
                            {
                                if (_UDP_Buffer_Received.ContainsKey(token))
                                {
                                    // 组包
                                    var data = _UDP_Buffer_Received[token];
                                    data.Buffer = CustomConvert.expand(data.Buffer, data.Buffer.Length + len);
                                    Buffer.BlockCopy(buffer, 0, data.Buffer, data.Buffer.Length - len, len);
                                    if (data.Buffer.Length >= data.Buffer[0])
                                    {
                                        // 包长度足够之后从暂存缓存中移除节点
                                        _UDP_Buffer_Received.Remove(token);
                                        // 发送消息
                                        OnReceivedData(this, new AsyncUserDataEvent()
                                        {
                                            Data = data
                                        });
                                    }
                                }
                                else
                                {
                                    if (len >= buffer[0])
                                    {
                                        // 如果收到的是完整的包则直接发给前台处理
                                        if (null != OnReceivedData)
                                        {
                                            var aude = new AsyncUserDataEvent();
                                            aude.Data = _bufferPool.Get();
                                            aude.Data.SetDataEvent(ip, port, buffer, len);
                                            aude.Data.PackageType = AsyncDataPackageType.UDP;
                                            OnReceivedData(this, aude);
                                        }
                                    }
                                    else
                                    {
                                        //var aude = new AsyncUserDataEvent();
                                        var data = _bufferPool.Get();
                                        data.SetDataEvent(ip, port, buffer, len);
                                        data.PackageType = AsyncDataPackageType.UDP;
                                        _UDP_Buffer_Received.Add(token, data);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    string a = e.Message;
                }
            }
        }