Beispiel #1
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;
                 //客户端信息
                 AsyncUserToken userToken = (AsyncUserToken)asyniar.UserToken;
                 userToken.ReceiveEventArgs = asyniar;
                 userToken.Socket           = e.AcceptSocket;
                 userToken.ConnectTime      = DateTime.Now;
                 userToken.Remote           = e.AcceptSocket.RemoteEndPoint;
                 userToken.IPAddress        = ((IPEndPoint)(e.AcceptSocket.RemoteEndPoint)).Address;
                 //userToken.SendEventArgs = asyniar;
                 lock (m_clients) { m_clients.Add(userToken); }
                 //Log4Debug(String.Format("客户 {0} 连入, 共有 {1} 个连接。", s.RemoteEndPoint.ToString(), _clientCount));
                 //SockList.Add(s);
                 if (!s.ReceiveAsync(asyniar))//投递接收请求
                 {
                     ProcessReceive(asyniar);
                 }
             }
             catch (SocketException ex)
             {
                 //Log4Debug(String.Format("接收客户 {0} 数据出错, 异常信息: {1} 。", s.RemoteEndPoint, ex.ToString()));
                 //TODO 异常处理
             }
             if (e.SocketError == SocketError.OperationAborted)
             {
                 return;
             }
             //投递下一个接受请求
             StartAccept(e);
         }
     }
     else if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0)
     {
         //Log4Debug("Client: 服务器断开连接 ");
         CloseClientSocket(e);
     }
 }
Beispiel #2
0
        /// <summary>
        /// client 连接或断开时
        /// </summary>
        /// <param name="num"></param>
        /// <param name="token"></param>
        static void m_socket_ClientNumberChange(int num, AsyncUserToken token)
        {
            string msg = "";

            if (num > 0)
            {
                msg = string.Format("{0},{1}已连接", num, token.Remote.ToString());
                Log.Info(msg);
            }

            if (num < 0)
            {
                msg = string.Format("{0},{1}断开连接", num, token.Remote.ToString());
            }

            Log.Info(msg);
        }
Beispiel #3
0
 private void ProcessSend(SocketAsyncEventArgs e)
 {
     if (e.SocketError == SocketError.Success)
     {
         AsyncUserToken token = (AsyncUserToken)e.UserToken; //Done transmitting
         e.SetBuffer(e.Offset, receiveBufferSize);           //Restore buffer size for the receiver
         //Start an asynchronous request to receive
         if (!token.Socket.ReceiveAsync(e))                  //I/O completed synchronously, no event raised, must handle now
         {
             ProcessReceive(e);
         }
     }
     else
     {
         CloseClientSocket(e);
     }
 }
Beispiel #4
0
 // This method is invoked when an asynchronous send operation completes.
 // The method issues another receive on the socket to read any additional
 // data sent from the client
 //
 // <param name="e"></param>
 private void ProcessSend(SocketAsyncEventArgs e)
 {
     if (e.SocketError == SocketError.Success)
     {
         // done echoing data back to the client
         AsyncUserToken token = (AsyncUserToken)e.UserToken;
         // read the next block of data send from the client
         bool willRaiseEvent = token.Socket.ReceiveAsync(e);
         if (!willRaiseEvent)
         {
             ProcessReceive(e);
         }
     }
     else
     {
         CloseClientSocket(e);
     }
 }
Beispiel #5
0
 /// <summary>
 /// 发送完成时处理函数
 /// </summary>
 /// <param name="e">与发送完成操作相关联的SocketAsyncEventArg对象</param>
 private void ProcessSend(SocketAsyncEventArgs e)
 {
     if (e.SocketError == SocketError.Success)
     {
         //Socket s = (Socket)e.UserToken;
         AsyncUserToken token = (AsyncUserToken)e.UserToken;
         //TODO
         if (!token.Socket.ReceiveAsync(e))//为接收下一段数据,投递接收请求,这个函数有可能同步完成,这时返回false,并且不会引发SocketAsyncEventArgs.Completed事件
         {
             //同步接收时处理接收完成事件
             //ProcessReceive(e);
             ProcessSend(e);
         }
     }
     else
     {
         CloseClientSocket(e);
     }
 }
Beispiel #6
0
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            // Close the socket associated with the client
            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error shuttin down socket: Source {0}, Message: {1}", ex.Source, ex.Message);
            }
            token.Socket.Close();

            _maxNumberAcceptedClients.Release();
            Interlocked.Decrement(ref _numConnectedSockets);
            Debug.WriteLine("Connecttion dropped, {0} remaining.", _numConnectedSockets);
            Push(e);    //Free the SocketAsyncEventArg, so that they can be reused by another client
        }
Beispiel #7
0
        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            try
            {
                Interlocked.Increment(ref m_clientCount);
                // Get the socket for the accepted client connection and put it into the
                //ReadEventArg object user token
                SocketAsyncEventArgs readEventArgs = m_pool.Pop();
                AsyncUserToken       userToken     = (AsyncUserToken)readEventArgs.UserToken;

                userToken.usernamr    = "Mtt";
                userToken.Socket      = e.AcceptSocket;
                userToken.ConnectTime = DateTime.Now;
                userToken.Remote      = e.AcceptSocket.RemoteEndPoint;
                userToken.IPAddress   = ((IPEndPoint)(e.AcceptSocket.RemoteEndPoint)).Address;

                lock (m_clients) { m_clients.Add(userToken); }

                if (ClientNumberChange != null)
                {
                    ClientNumberChange(1, userToken);
                }
                if (!e.AcceptSocket.ReceiveAsync(readEventArgs))
                {
                    ProcessReceive(readEventArgs);
                }
            }
            catch (Exception me)
            {
                Console.WriteLine(me.Message);
            }

            // Accept the next connection request
            if (e.SocketError == SocketError.OperationAborted)
            {
                return;
            }
            StartAccept(e);
        }
Beispiel #8
0
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            // close the socket associated with the client
            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            // throws if client process has already closed
            catch (Exception) { }
            token.Socket.Close();

            // decrement the counter keeping track of the total number of clients connected to the server
            Interlocked.Decrement(ref m_numConnectedSockets);

            // Free the SocketAsyncEventArg so they can be reused by another client
            m_readWritePool.Push(e);

            m_maxNumberAcceptedClients.Release();
            Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets);
        }
        public override void MessageReceive(AsyncUserToken token, int cmd, IMessage message)
        {
            Cmd command = (Cmd)cmd;

            switch (command)
            {
            case Cmd.GmCommand:
                break;

            case Cmd.Login:
                login.MessageReceive(token, cmd, message);
                break;

            case Cmd.CreateRole:
                break;

            case Cmd.SetRolename:
                break;

            case Cmd.SceneLoad:
                break;

            case Cmd.SceneRole:
                break;

            case Cmd.MailOpen:
                break;

            case Cmd.MailAtch:
                break;

            case Cmd.MailDel:
                break;

            default:
                break;
            }
        }
Beispiel #10
0
        /// <summary>
        /// 停止服务
        /// </summary>
        public void Stop()
        {
            foreach (var item in m_clients)
            {
                try
                {
                    AsyncUserToken token = item;
                    token.Socket.Shutdown(SocketShutdown.Both);
                }
                catch (Exception) { }
            }

            try
            {
                if (m_clients.Count > 0)
                {
                    listenSocket.Shutdown(SocketShutdown.Both);
                }
            }
            catch (Exception e)//当socket 无连接时(即没有可用已连接的client)
            {
                // listenSocket.Disconnect(false);///因为无可用的socket连接,此方法不可用
                Console.WriteLine(e.Message);
            }
            finally
            {
                listenSocket.Close();
                //通知界面,server已经停止
                if (ServerStopedEvent != null)
                {
                    ServerStopedEvent();
                }
                lock (m_clients)
                {
                    m_clients.Clear();
                }
            }
        }
Beispiel #11
0
        //关闭客户端
        private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = e.UserToken as AsyncUserToken;

            lock (m_clients) { m_clients.Remove(token); }
            //如果有事件,则调用事件,发送客户端数量变化通知
            if (ClientNumberChange != null)
            {
                ClientNumberChange(-1, token);
            }
            // close the socket associated with the client
            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            catch (Exception) { }
            token.Socket.Close();
            // decrement the counter keeping track of the total number of clients connected to the server
            Interlocked.Decrement(ref m_clientCount);
            m_maxNumberAcceptedClients.Release();
            // Free the SocketAsyncEventArg so they can be reused by another client
            e.UserToken = new AsyncUserToken();
            m_pool.Push(e);
        }
Beispiel #12
0
        // This method is invoked when an asynchronous receive operation completes.
        // If the remote host closed the connection, then the socket is closed.
        // If data was received then the data is echoed back to the client.
        //
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            // check if the remote host closed the connection
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
            {
                //increment the count of the total bytes receive by the server
                Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
                Console.WriteLine("The server has read a total of {0} bytes", m_totalBytesRead);

                //echo the data received back to the client
                e.SetBuffer(e.Offset, e.BytesTransferred);
                bool willRaiseEvent = token.Socket.SendAsync(e);
                if (!willRaiseEvent)
                {
                    ProcessSend(e);
                }
            }
            else
            {
                CloseClientSocket(e);
            }
        }
 public override void ClientConnect(AsyncUserToken token)
 {
     Console.WriteLine($"[ {token.UserSocket.RemoteEndPoint.ToString()} ] 连接");
 }
 public override void ClientClose(AsyncUserToken token, string error)
 {
     Console.WriteLine($"[ {token.UserSocket.ToString()} ] 断开连接,{error}");
 }
Beispiel #15
0
        // This method is invoked when an asynchronous receive operation completes.
        // If the remote host closed the connection, then the socket is closed.
        // If data was received then the data is echoed back to the client.
        //
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            try
            {
                // check if the remote host closed the connection
                AsyncUserToken token = (AsyncUserToken)e.UserToken;
                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                {
                    //读取数据
                    byte[] data = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, data, 0, e.BytesTransferred);
                    lock (token.Buffer)
                    {
                        token.Buffer.AddRange(data);
                    }
                    //注意:你一定会问,这里为什么要用do-while循环?
                    //如果当客户发送大数据流的时候,e.BytesTransferred的大小就会比客户端发送过来的要小,
                    //需要分多次接收.所以收到包的时候,先判断包头的大小.够一个完整的包再处理.
                    //如果客户短时间内发送多个小数据包时, 服务器可能会一次性把他们全收了.
                    //这样如果没有一个循环来控制,那么只会处理第一个包,
                    //剩下的包全部留在token.Buffer中了,只有等下一个数据包过来后,才会放出一个来.
                    do
                    {
                        //判断包的长度
                        byte[] lenBytes   = token.Buffer.GetRange(0, 4).ToArray();
                        int    packageLen = BitConverter.ToInt32(lenBytes, 0);
                        if (packageLen > token.Buffer.Count - 4)
                        {   //长度不够时,退出循环,让程序继续接收
                            break;
                        }

                        //包够长时,则提取出来,交给后面的程序去处理
                        byte[] rev = token.Buffer.GetRange(4, packageLen).ToArray();
                        //从数据池中移除这组数据
                        lock (token.Buffer)
                        {
                            token.Buffer.RemoveRange(0, packageLen + 4);
                        }
                        //将数据包交给后台处理,这里你也可以新开个线程来处理.加快速度.
                        if (ReceiveClientData != null)
                        {
                            ReceiveClientData(token, rev);
                        }
                        //这里API处理完后,并没有返回结果,当然结果是要返回的,却不是在这里, 这里的代码只管接收.
                        //若要返回结果,可在API处理中调用此类对象的SendMessage方法,统一打包发送.不要被微软的示例给迷惑了.
                    } while (token.Buffer.Count > 4);

                    //继续接收. 为什么要这么写,请看Socket.ReceiveAsync方法的说明
                    if (!token.Socket.ReceiveAsync(e))
                    {
                        this.ProcessReceive(e);
                    }
                }
                else
                {
                    CloseClientSocket(e);
                }
            }
            catch (Exception xe)
            {
                Console.WriteLine(xe.Message + "\r\n" + xe.StackTrace);
            }
        }