private void HandleAsyncReceive(IAsyncResult res) { ServerStateObject state = (ServerStateObject)res.AsyncState; TClient client = state.client; try { // read data from the client socket int read = client.Socket.EndReceive(res); // data was read from client socket if (read > 0) { using (MemoryStream stream = new MemoryStream(state.buffer, 0, read, false, true)) ReceiveMessage(client, stream); // begin receiving again after handling, so we can re-usse the same stateobject/buffer without issues. client.Socket.BeginReceive(state.buffer, 0, ServerStateObject.BufferSize, 0, HandleAsyncReceive, state); } else { // connection was closed. Log.Info("Client closed connection: {0}", client.Socket.RemoteEndPoint); client.Close(); } } catch (SocketException e) { switch (e.SocketErrorCode) { // TODO: More SocketError handling. case SocketError.ConnectionReset: Log.ErrorException(string.Format("Client {0} issued a ConnectionReset error.", client), e); client.Close(); break; default: // Swallow the exception, but make sure a log is created and close the client. //Log.ErrorException(string.Format("Unhandled SocketException (Error:{0}) for client {1} while receiving. Closing the client.", e.SocketErrorCode, client.ToString()), e); client.Close(); break; } } catch (Exception e) { // Note: State for this client may have been corrupted at this point, this is // an important issue when we reach this handler. This will force process to close. // Todo: Close anything else if needed (i.e. session, this will catch every unhandled exception in the handler, ect). Log.ErrorException("Exception occured while handling a packet", e); // We're most likely crashing, client is going to close anyway, // maybe it's better not to do more with it. //client.Close(); throw; } }
private void HandleAsyncConnection(IAsyncResult res) { m_listener.BeginAcceptTcpClient(HandleAsyncConnection, m_listener); TcpClient client = m_listener.EndAcceptTcpClient(res); if (!IsClientAccepted(client.Client)) { Log.Warn("Refused connection from {0}", client.Client.RemoteEndPoint); return; } Log.Info("Openned connection from {0}", client.Client.RemoteEndPoint); ServerStateObject state = new ServerStateObject(); state.client = CreateClient(client.Client); ClientConnected(state.client); client.Client.BeginReceive(state.buffer, 0, ServerStateObject.BufferSize, SocketFlags.None, HandleAsyncReceive, state); }
//private void StateChangedCallback(ServerStateObject param) //{ //} protected void StartListening(ServerStateObject context) { //context.StateChangedHandler = new Action<ServerStateObject>(StateChangedCallback); // Data buffer for incoming data. byte[] bytes = new Byte[1024]; // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); IPAddress ipAddress = ipHostInfo.AddressList.FirstOrDefault(ip => { return ip.AddressFamily == AddressFamily.InterNetwork; }); if (ipAddress == null) { this.OnError(ErrorType.Error, new NotSupportedException("IPv4 주소만 지원합니다. 컴퓨터에 IPv4 주소로 인터넷이 연결되어 있는지 확인하세요")); return; } this.HostAddress = ipAddress; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, context.Port); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100); this.OnStartListening(listener); while (context.IsListening) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections. Console.WriteLine("Waiting for a connection..."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); // Wait until a connection is made before continuing. allDone.WaitOne(TimeSpan.FromMilliseconds(1000)); } this.OnStopListening(listener); } catch (Exception e) { Console.WriteLine(e.ToString()); this.OnError(ErrorType.Error, e); } Console.WriteLine("\nPress ENTER to continue..."); Console.Read(); }