static void AcceptCallback(IAsyncResult ar) { Socket serverSocket = (Socket)ar.AsyncState; Socket clientSocket = serverSocket.EndAccept(ar); WriteConsole("Accepted connection."); BeginReceive(clientSocket); BeginAccept(serverSocket); string clientName = GetUniqueName(); ClientInformation clientInformation = new ClientInformation(clientSocket, clientName, GetFirstUnusedClientId()); string connectionResponse = XMLManager.Serialize(new ConnectionResponse(clientName, _clients.Select(c => c.Name).ToList())); BeginSend(clientInformation, connectionResponse); string clientConnect = XMLManager.Serialize(new ClientConnect(clientName)); foreach (ClientInformation client in _clients) { BeginSend(client, clientConnect); } _clients.Add(clientInformation); }
static void BeginSend(ClientInformation clientSocket, string text) { byte[] dataToSend = Encoding.UTF8.GetBytes(text); clientSocket.Socket.BeginSend(dataToSend, 0, dataToSend.Length, SocketFlags.None, new AsyncCallback(SendCallback), clientSocket.Socket); WriteConsole(string.Format("Sending data to client {0}: {1}", clientSocket.Name, text)); }
static void ReceiveCallBack(IAsyncResult ar) { StateObject state = (StateObject)ar.AsyncState; Socket clientSocket = state.Socket; int bytesRead = clientSocket.EndReceive(ar); string text = Encoding.UTF8.GetString(state.Buffer, 0, bytesRead); ClientInformation senderClient = GetClientInformation(clientSocket); WriteConsole(string.Format("Received data from client {0}: {1}", senderClient.Name, text)); if (!string.IsNullOrEmpty(text)) { object element = XMLManager.Deserialize(text); if (element is SendMessage sendMessage) { BroadcastMessage broadcastMessage = new BroadcastMessage(senderClient.Name, sendMessage.Text); string broadcastMessageText = XMLManager.Serialize(broadcastMessage); foreach (ClientInformation client in _clients) { BeginSend(client, broadcastMessageText); } } else if (element is ChangeNameRequest cnr) { if (string.IsNullOrEmpty(cnr.Name)) { BeginSend(senderClient, XMLManager.Serialize(new ErrorResponse((int)ErrorCode.InvalidName))); } else if (IsNameUnique(cnr.Name)) { string changeNameResponseText = XMLManager.Serialize(new ChangeNameResponse(senderClient.Name, cnr.Name)); foreach (ClientInformation client in _clients) { BeginSend(client, changeNameResponseText); } senderClient.Name = cnr.Name; } else { BeginSend(senderClient, XMLManager.Serialize(new ErrorResponse((int)ErrorCode.NameAlreadyExists))); } } else if (element is ChallengeRequest challengeRequest) { ClientInformation challengeeClient = GetClientInformation(challengeRequest.ChallengeeName); if (challengeeClient.State == ClientState.Available) { senderClient.ChangeStateToChallenge(challengeeClient.Id); challengeeClient.ChangeStateToChallenge(senderClient.Id); BeginSend(senderClient, XMLManager.Serialize(new ChallengePendingResponse() { ChallengeeName = challengeRequest.ChallengeeName })); BeginSend(challengeeClient, XMLManager.Serialize(new ChallengeRequest(senderClient.Name))); } else if (challengeeClient.State == ClientState.Challenge) { BeginSend(senderClient, XMLManager.Serialize(new ErrorResponse((int)ErrorCode.ClientAlreadyChallenged))); } else if (challengeeClient.State == ClientState.Duel) { BeginSend(senderClient, XMLManager.Serialize(new ErrorResponse((int)ErrorCode.ClientAlreadyInDuel))); } else { throw new InvalidOperationException("Unknown client state."); } } else if (element is CancelChallengeRequest) { ClientInformation challengeeClient = GetClientInformation(senderClient.OtherClientId); senderClient.ChangeStateToAvailable(); challengeeClient.ChangeStateToAvailable(); BeginSend(senderClient, XMLManager.Serialize(new CancelChallengeRequest())); BeginSend(challengeeClient, XMLManager.Serialize(new CancelChallengeResponse() { Challenger = senderClient.Name })); } else if (element is DeclineChallengeRequest) { ClientInformation challengerClient = GetClientInformation(senderClient.OtherClientId); senderClient.ChangeStateToAvailable(); challengerClient.ChangeStateToAvailable(); BeginSend(senderClient, XMLManager.Serialize(new DeclineChallengeRequest())); BeginSend(challengerClient, XMLManager.Serialize(new DeclineChallengeResponse() { Challengee = senderClient.Name })); } else if (element is AcceptChallengeRequest) { //TODO: implement properly ClientInformation challengerClient = GetClientInformation(senderClient.OtherClientId); senderClient.ChangeStateToAvailable(); challengerClient.ChangeStateToAvailable(); BeginSend(senderClient, XMLManager.Serialize(new AcceptChallengeRequest())); BeginSend(challengerClient, XMLManager.Serialize(new AcceptChallengeResponse() { Challengee = senderClient.Name })); } else { throw new ArgumentOutOfRangeException("element"); } BeginReceive(clientSocket); } else { senderClient.Socket.Shutdown(SocketShutdown.Both); senderClient.Socket.Close(); _clients.Remove(senderClient); WriteConsole(string.Format("{0} disconnected.", senderClient.Name)); ClientDisconnect clientDisconnect = new ClientDisconnect(senderClient.Name); string clientDisconnectText = XMLManager.Serialize(clientDisconnect); foreach (ClientInformation client in _clients) { BeginSend(client, clientDisconnectText); } } }