예제 #1
0
        private void AcceptLoop()
        {
            while (m_State > 0)
            {
                m_ListenWatcher.Reset();
                try
                {
                    lock (m_ListenWatcher)
                    {
                        if (m_ListenSocket != null)
                        {
                            m_ListenSocket.BeginAccept(new AsyncCallback(AcceptCallback), m_ListenSocket);
                        }
                    }

                    m_ListenWatcher.WaitOne();
                }
                catch (Exception ex)
                {
                    if (m_IoHandler != null)
                    {
                        try
                        {
                            m_IoHandler.OnError(null, Session.ERROR_CONNECT, ex.Message);
                        }
                        catch { }
                    }
                }
            }
        }
예제 #2
0
        void Update()
        {
            // StartServer나 StartClient가 호출되어 초기화되기 전엔 아래의 코드를 실행하지 않음
            if (_handler == null)
            {
                return;
            }

            // 핸들러가 모든 리소스를 정리하고 끝마칠 준비가 돼야 제거한다.
            // 서버나 클라이언트를 종료하고 난 후에도 처리해야할 이벤트가 있을 수 있기 때문이다.
            if (_handler.IsDead())
            {
                _handler.OnRemoved();
                _handler = null;
                IsOnline = false;
                IsServer = true;
                return;
            }

            // Notice we process all network events until we get a 'Nothing' response here.
            // Often people just process a single event per frame, and that results in very poor performance.
            var noEventsLeft = false;

            while (!noEventsLeft)
            {
                byte errorCode;
                int  dataSize;
                int  channelId;
                int  connectionId;
                int  hostId;

                var netEventType = NetworkTransport.Receive(
                    out hostId,
                    out connectionId,
                    out channelId,
                    _buffer,
                    _buffer.Length,
                    out dataSize,
                    out errorCode);

                var error = (NetworkError)errorCode;
                if (error != NetworkError.Ok)
                {
                    Debug.Log(string.Format("NetworkTransport error : {0}", error));
                    _handler.OnError(hostId, connectionId, channelId, error);
                    return;
                }

                switch (netEventType)
                {
                case NetworkEventType.Nothing:
                    noEventsLeft = true;
                    break;

                case NetworkEventType.ConnectEvent:
                    _handler.OnConnectEvent(hostId, connectionId, channelId);
                    break;

                case NetworkEventType.DataEvent:
                    _handler.OnDataEvent(hostId, connectionId, channelId, _buffer, dataSize);
                    break;

                case NetworkEventType.DisconnectEvent:
                    _handler.OnDisconnectEvent(hostId, connectionId, channelId);
                    break;
                }
            }
        }
예제 #3
0
        public void Open()
        {
            if (m_State >= 0)
            {
                return;               // do nothing if the session is already in "connected" or "connecting" state
            }
            if (m_SessionGroup != null)
            {
                // first, add it to group ...
                m_SessionGroup.AddSession(m_Id, this);
            }

            m_LastReadTime  = DateTime.Now;
            m_LastWriteTime = DateTime.Now;

            Socket socket = GetSocket();

            if (socket != null)
            {
                try
                {
                    m_State      = 1;
                    m_RemoteIp   = IPAddress.Parse(((IPEndPoint)socket.RemoteEndPoint).Address.ToString()).ToString();
                    m_RemotePort = ((IPEndPoint)socket.RemoteEndPoint).Port;
                }
                catch { }
            }

            try
            {
                // make sure the queue is clean
                if (m_OutgoingMessageQueue.Count > 0)
                {
                    lock (m_OutgoingMessageQueue) m_OutgoingMessageQueue.Clear();
                }
                // make sure the queue is clean
                if (m_IncomingMessageQueue.Count > 0)
                {
                    m_IncomingMessageQueue.Clear(); // incoming data should be processed in single thread
                }
            }
            catch { }

            if (m_IoHandler != null)
            {
                try
                {
                    m_IoHandler.OnConnect(this);
                }
                catch { }
            }

            try
            {
                if (socket != null)
                {
                    if (m_ReadBuffer == null || m_ReadBuffer.Length <= 0)
                    {
                        m_ReadBuffer = new Byte[socket.ReceiveBufferSize];
                    }
                }

                if (m_Stream != null)
                {
                    m_Stream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length, new AsyncCallback(ReceiveCallback), this);
                }
            }
            catch (Exception ex)
            {
                if (m_IoHandler != null)
                {
                    try
                    {
                        m_IoHandler.OnError(this, ERROR_RECEIVE, ex);
                    }
                    catch { }
                }
            }
        }
예제 #4
0
        public void Connect(string svrIp, int svrPort, int timeout = 0)
        {
            IPEndPoint remoteEP  = null;
            IPAddress  ipAddress = null;

            try
            {
                if (ipAddress == null)
                {
                    try
                    {
                        // first, we assume input is IP string
                        ipAddress = IPAddress.Parse(svrIp);
                    }
                    catch
                    {
                        ipAddress = null;
                    }
                }

                if (ipAddress == null)
                {
                    try
                    {
                        // and now, input string might be a domain name ...

                        IPHostEntry ipHostInfo = Dns.GetHostEntry(svrIp);
                        foreach (IPAddress addr in ipHostInfo.AddressList)
                        {
                            // try to accept IPv4 first ...
                            if (addr.AddressFamily == AddressFamily.InterNetwork)
                            {
                                ipAddress = addr;
                                break;
                            }
                        }

                        if (ipAddress == null)
                        {
                            // try to accept any available ...
                            foreach (IPAddress addr in ipHostInfo.AddressList)
                            {
                                ipAddress = addr;
                                break;
                            }
                        }
                    }
                    catch { }
                }

                if (ipAddress == null)
                {
                    return;
                }

                Disconnect();

                m_TargetServer = svrIp;

                remoteEP = new IPEndPoint(ipAddress, svrPort);

                // Create a TCP/IP socket.
                m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }
            catch (Exception ex)
            {
                if (m_IoHandler != null)
                {
                    try
                    {
                        m_IoHandler.OnError(null, Session.ERROR_CONNECT, ex);
                    }
                    catch { }
                }
                Disconnect();
            }

            if (m_Socket == null || remoteEP == null || ipAddress == null)
            {
                return;
            }

            // set session's io buffer size to a global value by default
            // but you still can change them with different values in session's OnConnect event function
            m_Socket.ReceiveBufferSize = m_IoBufferSize;
            m_Socket.SendBufferSize    = m_IoBufferSize;

            // Connect to the remote endpoint.
            try
            {
                IAsyncResult result  = null;
                bool         success = false;

                lock (m_SessionGroup)
                {
                    m_State = 0;

                    m_RemoteIp   = IPAddress.Parse(ipAddress.ToString()).ToString();
                    m_RemotePort = svrPort;

                    result = m_Socket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), this);
                }

                if (result != null && timeout > 0)
                {
                    success = result.AsyncWaitHandle.WaitOne(timeout * 1000, true);
                }
                else
                {
                    success = result != null;
                }

                if (!success)
                {
                    // NOTE, MUST CLOSE THE SOCKET
                    if (m_IoHandler != null)
                    {
                        try
                        {
                            m_IoHandler.OnError(null, Session.ERROR_CONNECT, new Exception("Connection timeout"));
                        }
                        catch { }
                    }

                    // close socket
                    Disconnect();
                }
            }
            catch (Exception ex)
            {
                if (m_IoHandler != null)
                {
                    try
                    {
                        m_IoHandler.OnError(null, Session.ERROR_CONNECT, ex);
                    }
                    catch { }
                }

                // close socket
                Disconnect();
            }
        }