private static void TryAcceptConnection <T>(IAsyncResult AR) where T : IClientConnectable { if (listenerClosed) { return; } try { Socket newSocket = listenerSocket.EndAccept(AR); IClientConnectable newClient = (T)Activator.CreateInstance(typeof(T), new object[] { newSocket, ++ClientCounter }); AddClient(newClient); newClient.Socket.BeginReceive(newClient.Buffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(OnReceiveData), newClient); listenerSocket.BeginAccept(new AsyncCallback(TryAcceptConnection <T>), null); if (TryTransmitToClient(newClient, "\nYou are now connected to the network server. For connection-related support, type '/help'.\n\n")) { TryTransmitToClient(newClient, newClient.GetImmediateReplyForClient()); } } catch (Exception ex) { ErrorMessage(ex); } }
// ======================================================================================= // ASYNC RECEIVER // ======================================================================================= private static void OnReceiveData(IAsyncResult ar) { IClientConnectable thisClient = (IClientConnectable)ar.AsyncState; if (thisClient == null) { return; } if (!Clients.Contains(thisClient)) { Log($"Discarding listener for {thisClient}.\n"); return; } int bytesReceived = 0; if (thisClient.Socket.Connected) { try { bytesReceived = thisClient.Socket.EndReceive(ar); if (bytesReceived > 0) { string incomingData = Encoding.ASCII.GetString(thisClient.Buffer, 0, bytesReceived).Trim(); if (incomingData.Length > 0 && incomingData.Substring(0, 1) == "/") { string feedback = HandleConsoleCommands(thisClient, incomingData); if (TryTransmitToClient(thisClient, $"{feedback}\n")) { thisClient.Socket.BeginReceive(thisClient.Buffer, 0, BufferSize, 0, new AsyncCallback(OnReceiveData), thisClient); } } else { Log($"{thisClient.Nickname}: [{incomingData}]\n"); thisClient.HandleInputFromClientToServer(incomingData); if (TryTransmitToClient(thisClient, thisClient.GetImmediateReplyForClient())) { thisClient.Socket.BeginReceive(thisClient.Buffer, 0, BufferSize, 0, new AsyncCallback(OnReceiveData), thisClient); } } } } catch (SocketException ex) { switch (ex.ErrorCode) { case 10054: Log($"Error ({ex.ErrorCode}): {thisClient.Nickname} dropped!\n"); RemoveClient(thisClient, false); break; default: ErrorMessage($"SocketException ({ex.ErrorCode}): {ex.Message}!", ex); break; } if (thisClient.Socket.Connected) { thisClient.Socket.Close(); } } catch (Exception ex) { ErrorMessage(ex); } } }