Beispiel #1
0
        private void CloseClientSocket(string uid)
        {
            if (uid == string.Empty || uid == "")
            {
                return;
            }
            SocketAsyncEventArgsWithId saeaw = readWritePool.FindByUID(uid);

            if (saeaw == null)
            {
                return;
            }
            Socket s = saeaw.ReceiveSAEA.UserToken as Socket;

            try
            {
                s.Shutdown(SocketShutdown.Both);
            }
            catch (Exception)
            {
                //客户端已经关闭
            }
            this.semaphoreAcceptedClients.Release();
            Interlocked.Decrement(ref this.numConnections);
            this.readWritePool.Push(saeaw);
        }
 /// <summary>
 /// 把一个使用完的连接放回连接池。
 /// </summary>
 /// <param name="item"></param>
 internal void Push(SocketAsyncEventArgsWithId item)
 {
     if (item == null)
     {
         throw new ArgumentNullException("SocketAsyncEventArgsWithId对象为空");
     }
     if (item.State == true)
     {
         if (busypool.Keys.Count != 0)
         {
             if (busypool.Keys.Contains(item.UID))
             {
                 busypool.Remove(item.UID);
                 keys.Remove(item.UID);
             }
             else
             {
                 throw new ArgumentException("SocketAsyncEventWithId不在忙碌队列中");
             }
         }
         else
         {
             throw new ArgumentException("忙碌队列为空");
         }
     }
     item.UID   = "-1";
     item.State = false;
     lock (this.pool)
     {
         this.pool.Push(item);
     }
 }
Beispiel #3
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            if (e.LastOperation != SocketAsyncOperation.Accept)    //检查上一次操作是否是Accept,不是就返回
            {
                return;
            }
            if (e.BytesTransferred <= 0)    //检查发送的长度是否大于0,不是就返回
            {
                return;
            }
            string UID = GetIDByIP((e.AcceptSocket.RemoteEndPoint as IPEndPoint).Address.ToString());   //根据IP获取用户的UID

            if (UID == string.Empty || UID == null || UID == "")
            {
                return;
            }
            if (readWritePool.BusyPoolContains(UID))    //判断现在的用户是否已经连接,避免同一用户开两个连接
            {
                return;
            }
            SocketAsyncEventArgsWithId readEventArgsWithId = this.readWritePool.Pop(UID);

            readEventArgsWithId.ReceiveSAEA.UserToken = e.AcceptSocket;
            readEventArgsWithId.SendSAEA.UserToken    = e.AcceptSocket;
            Interlocked.Increment(ref this.numConnections);
            this.StartAccept(e);
        }
Beispiel #4
0
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="uid">要发送的用户的uid</param>
        /// <param name="msg">消息体</param>
        public void Send(string uid, string msg)
        {
            if (uid == string.Empty || uid == "" || msg == string.Empty || msg == "")
            {
                return;
            }
            SocketAsyncEventArgsWithId socketWithId = readWritePool.FindByUID(uid);

            if (socketWithId == null)
            {
                //说明用户已经断开
                //100   发送成功
                //200   发送失败
                //300   用户不在线
                //其它  表示异常的信息
                OnSended(uid, "300");
            }
            else
            {
                MySocketAsyncEventArgs e = socketWithId.SendSAEA;
                if (e.SocketError == SocketError.Success)
                {
                    int i = 0;
                    try
                    {
                        string message    = @"[lenght=" + msg.Length + @"]" + msg;
                        byte[] sendbuffer = Encoding.Unicode.GetBytes(message);
                        e.SetBuffer(sendbuffer, 0, sendbuffer.Length);
                        Boolean willRaiseEvent = (e.UserToken as Socket).SendAsync(e);
                        if (!willRaiseEvent)
                        {
                            this.ProcessSend(e);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (i <= 5)
                        {
                            i++;
                            //如果发送出现异常就延迟0.01秒再发
                            Thread.Sleep(10);
                            Send(uid, msg);
                        }
                        else
                        {
                            OnSended(uid, ex.ToString());
                        }
                    }
                }
                else
                {
                    OnSended(uid, "200");
                    this.CloseClientSocket(((MySocketAsyncEventArgs)e).UID);
                }
            }
        }
        /// <summary>
        /// 查找在线用户连接,返回这个连接。
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        internal SocketAsyncEventArgsWithId FindByUID(string uid)
        {
            SocketAsyncEventArgsWithId si = null;

            if (busypool.ContainsKey(uid))
            {
                si = busypool[uid];
            }
            return(si);
        }
Beispiel #6
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            try
            {
                if (e.LastOperation != SocketAsyncOperation.Accept)    //检查上一次操作是否是Accept,不是就返回
                {
                    return;
                }
                //if (e.BytesTransferred <= 0)    //检查发送的长度是否大于0,不是就返回
                //    return;
                string UID = e.AcceptSocket.RemoteEndPoint.ToString();   //根据IP获取用户的UID
                if (UID == string.Empty || UID == null || UID == "")
                {
                    return;
                }

                SocketAsyncEventArgsWithId readEventArgsWithId = null;
                if (readWritePool.BusyPoolContains(UID))    //判断现在的用户是否已经连接,避免同一用户开两个连接
                {
                    readEventArgsWithId = readWritePool.busypool[UID];
                }
                else
                {
                    lock (this.readWritePool)
                    {
                        readEventArgsWithId = this.readWritePool.Pop(UID);
                    }
                }
                readEventArgsWithId.ReceiveSAEA.UserToken = e.AcceptSocket;
                readEventArgsWithId.SendSAEA.UserToken    = e.AcceptSocket;
                Interlocked.Increment(ref this.numConnections);
                lock (this.readWritePool)
                {
                    if (OnClientConnected != null)
                    {
                        //连接事件
                        OnClientConnected(this, new TcpClientConnectedEventArgs(UID));
                    }
                }

                Boolean willRaiseEvent = (readEventArgsWithId.ReceiveSAEA.UserToken as Socket).ReceiveAsync(readEventArgsWithId.ReceiveSAEA);
                if (!willRaiseEvent)
                {
                    ProcessReceive(readEventArgsWithId.ReceiveSAEA);
                }
            }
            catch (Exception EX)
            {
                throw EX;
            }
            finally
            {
                this.StartAccept(e);
            }
        }
Beispiel #7
0
        /// <summary>
        /// 服务端初始化
        /// </summary>
        public void Init()
        {
            this.bufferManager.InitBuffer();
            SocketAsyncEventArgsWithId readWriteEventArgWithId;

            for (Int32 i = 0; i < this.numConcurrence; i++)
            {
                readWriteEventArgWithId = new SocketAsyncEventArgsWithId();
                readWriteEventArgWithId.ReceiveSAEA.Completed += new EventHandler <SocketAsyncEventArgs>(OnReceiveCompleted);
                readWriteEventArgWithId.SendSAEA.Completed    += new EventHandler <SocketAsyncEventArgs>(OnSendCompleted);
                //只给接收的SocketAsyncEventArgs设置缓冲区
                this.bufferManager.SetBuffer(readWriteEventArgWithId.ReceiveSAEA);
                this.readWritePool.Push(readWriteEventArgWithId);
            }
            serverstate = ServerState.Inited;
        }
        internal SocketAsyncEventArgsWithId Pop(string uid)
        {
            if (uid == string.Empty || uid == "")
            {
                return(null);
            }
            SocketAsyncEventArgsWithId si = null;

            lock (this.pool)
            {
                si = this.pool.Pop();
            }
            si.UID   = uid;
            si.State = true;    //mark the state of pool is not the initial step
            busypool.Add(uid, si);
            return(si);
        }
        internal SocketAsyncEventArgsWithId FindByUID(string uid)
        {
            if (uid == string.Empty || uid == "")
            {
                return(null);
            }
            SocketAsyncEventArgsWithId si = null;

            foreach (string key in this.OnlineUID)
            {
                if (key == uid)
                {
                    si = busypool[uid];
                    break;
                }
            }
            return(si);
        }
Beispiel #10
0
        public void CloseClientSocket(string uid)
        {
            if (uid == string.Empty || uid == "")
            {
                return;
            }
            SocketAsyncEventArgsWithId saeaw = readWritePool.FindByUID(uid);

            if (saeaw == null)
            {
                return;
            }
            Socket r = saeaw.ReceiveSAEA.UserToken as Socket;
            Socket s = saeaw.SendSAEA.UserToken as Socket;

            try
            {
                r.Shutdown(SocketShutdown.Both);
                r.Close();
                Interlocked.Decrement(ref this.numConnections);
                this.readWritePool.Push(saeaw);
                this.semaphoreAcceptedClients.Release();
                lock (this.readWritePool)
                {
                    if (OnClientDisconnected != null)
                    {
                        //关闭连接事件
                        OnClientDisconnected(this, new TcpClientDisconnectedEventArgs(uid));
                    }
                }
            }
            catch (Exception)
            {
                //客户端已经关闭
            }
        }
Beispiel #11
0
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            try
            {
                string uid = ((MySocketAsyncEventArgs)e).UID;//用户Id
                if (e.LastOperation != SocketAsyncOperation.Receive)
                {
                    return;
                }
                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                {
                    Int32  byteTransferred = e.BytesTransferred;
                    byte[] received        = new byte[byteTransferred];
                    Buffer.BlockCopy(e.Buffer, e.Offset, received, 0, byteTransferred);
                    List <byte[]> msg = null;
                    //检查消息的准确性
                    lock (this.OnlineUID)
                    {
                        try
                        {
                            msg = this.readWritePool.busypool[uid].MsgHandler.GetActualObject(received);
                        }
                        catch (Exception ex)
                        {
                            SeatManage.SeatManageComm.WriteLog.Write(string.Format("根据消息头长度截取消息时遇到异常:{0}", ex.Message));
                            return;
                        }
                    }
                    foreach (byte[] m in msg)
                    {
                        SocketMsgData.SocketMsgBase smb = null;
                        try
                        {
                            smb = SeatManage.SeatManageComm.ByteSerializer.DeserializeByte <SocketMsgData.SocketMsgBase>(m);
                        }
                        catch (Exception ex)
                        {
                            SeatManage.SeatManageComm.WriteLog.Write(string.Format("消息反序列化失败:{0}", ex.Message));
                            return;
                        }
                        if (smb != null && smb.MsgType == SocketMsgData.TcpMsgDataType.Heartbeat)
                        {
                            if (this.readWritePool.BusyPoolContains(uid))
                            {
                                this.readWritePool.busypool[uid].UserOnLineCounter = 0;
                            }
                            else
                            {
                                SocketAsyncEventArgsWithId readEventArgsWithId = null;
                                lock (this.readWritePool)
                                {
                                    readEventArgsWithId = this.readWritePool.Pop(uid);
                                }

                                readEventArgsWithId.ReceiveSAEA.UserToken = e.AcceptSocket;
                                readEventArgsWithId.SendSAEA.UserToken    = e.AcceptSocket;
                                Interlocked.Increment(ref this.numConnections);
                                lock (this.readWritePool)
                                {
                                    if (OnClientConnected != null)
                                    {
                                        //连接事件
                                        OnClientConnected(this, new TcpClientConnectedEventArgs(uid));
                                    }
                                }
                            }


                            //else
                            //{
                            //    this.readWritePool.Pop(uid);
                            //    if (OnMsgReceived != null)
                            //    {
                            //        smb.MsgType = SocketMsgData.TcpMsgDataType.ClientToken;
                            //        OnMsgReceived(((MySocketAsyncEventArgs)e).UID, smb);
                            //    }
                            //}

                            Console.WriteLine("接收到{0}的心跳包", ((MySocketAsyncEventArgs)e).UID);
                        }
                        else if (OnMsgReceived != null)
                        {
                            OnMsgReceived(((MySocketAsyncEventArgs)e).UID, smb);
                        }
                    }
                    //可以在这里设一个停顿来实现间隔时间段监听,这里的停顿是单个用户间的监听间隔
                    //发送一个异步接受请求,并获取请求是否为成功
                    Boolean willRaiseEvent = (e.UserToken as Socket).ReceiveAsync(e);
                    if (!willRaiseEvent)
                    {
                        ProcessReceive(e);
                    }
                }
                else
                {
                    this.CloseClientSocket(((MySocketAsyncEventArgs)e).UID);
                }
            }
            catch (Exception ex)
            {
                SeatManage.SeatManageComm.WriteLog.Write(string.Format("Socket服务处理接收到的消息遇到异常:{0}", ex.Message));
            }
        }
Beispiel #12
0
        /// <summary>
        /// 发送信息,发送失败,重试五次
        /// </summary>
        /// <param name="uid">要发送的用户的uid</param>
        /// <param name="msg">消息体</param>
        public void Send(string uid, byte[] msg)
        {
            SocketAsyncEventArgsWithId socketWithId = readWritePool.FindByUID(uid);

            if (socketWithId == null)
            {
                //说明用户已经断开
                //100   发送成功
                //200   发送失败
                //300   用户不在线
                //其它  表示异常的信息
                if (OnSended != null)
                {
                    OnSended(uid, "300");
                }
                Console.WriteLine("{0:M} {1:t}:{2}", DateTime.Now, DateTime.Now, "用户不在线");
            }
            else
            {
                MySocketAsyncEventArgs e = socketWithId.SendSAEA;
                if (e.SocketError == SocketError.Success)
                {
                    int i = 0;
                    try
                    {
                        byte[]      arrayLength = BitConverter.GetBytes(msg.Length);
                        List <byte> listByte    = new List <byte>(arrayLength.Length + msg.Length);
                        listByte.AddRange(arrayLength);
                        listByte.AddRange(msg);
                        byte[] sendBuffer = listByte.ToArray();
                        e.SetBuffer(sendBuffer, 0, sendBuffer.Length);
                        Boolean willRaiseEvent = (e.UserToken as Socket).SendAsync(e);
                        if (!willRaiseEvent)
                        {
                            this.ProcessSend(e);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (i <= 5)
                        {
                            i++;
                            //如果发送出现异常就延迟0.01秒再发
                            Thread.Sleep(10);
                            Send(uid, msg);
                        }
                        else
                        {
                            if (OnSended != null)
                            {
                                OnSended(uid, ex.ToString());
                            }
                        }
                    }
                }
                else
                {
                    if (OnSended != null)
                    {
                        OnSended(uid, "200");
                    }
                    this.CloseClientSocket(((MySocketAsyncEventArgs)e).UID);
                }
            }
        }