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 { } } } } }
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; } } }
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 { } } } }
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(); } }