private async Task sendString(Commands.ClientCommands cCom, string str) { using (MemoryStream ms = new MemoryStream()) { //convert object to byte array byte[] data; if (str != "") { data = Encoding.Unicode.GetBytes(str); } //get data from string slightly differently than for objects because of encoding else { data = new byte[0]; } //send command number byte[] prep = BitConverter.GetBytes(Commands.getClientCommandUInt(cCom)); if (BitConverter.IsLittleEndian) //target computer might use different endian -> send and receive as big endian and if necessary, restore to little endian in client { Array.Reverse(prep); } await netS.WriteAsync(prep, 0, prep.Length); //write command (uint) to stream //send data size prep = BitConverter.GetBytes(data.Length); if (BitConverter.IsLittleEndian) { Array.Reverse(prep); } await netS.WriteAsync(prep, 0, prep.Length); //write length of data (int) to stream //send object await netS.WriteAsync(data, 0, data.Length); //write object to stream } }
private async Task receiveObject(Commands.ClientCommands cCom, int dataSize) { MemoryStream ms = new MemoryStream(await receiveData(dataSize)); BinaryFormatter bf = new BinaryFormatter(); ms.Position = 0; receivedData = bf.Deserialize(ms); //await saveClientCommand(cCom); }
private async Task sendObject(Commands.ClientCommands cCom, object obj) { //see e.g.: https://stackoverflow.com/questions/2316397/sending-and-receiving-custom-objects-using-tcpclient-class-in-c-sharp using (MemoryStream ms = new MemoryStream()) { //convert object to byte array byte[] data; if (obj != null) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); //serialise object to memory stream first -> can provide size of data in byte data = ms.ToArray(); //the object converted to a byte array } else { data = new byte[0]; } //send command number byte[] prep = BitConverter.GetBytes(Commands.getClientCommandUInt(cCom)); if (BitConverter.IsLittleEndian) //target computer might use different endian -> send and receive as big endian and if necessary, restore to little endian in client { Array.Reverse(prep); } await netS.WriteAsync(prep, 0, prep.Length); //write command (uint) to stream //send data size prep = BitConverter.GetBytes(data.Length); if (BitConverter.IsLittleEndian) { Array.Reverse(prep); } await netS.WriteAsync(prep, 0, prep.Length); //write length of data (int) to stream //send object await netS.WriteAsync(data, 0, data.Length); //write object to stream } }
private async Task sendCommand(Commands.ClientCommands cCom) { await sendObject(cCom, null); }
private async Task receiveString(Commands.ClientCommands cCom, int dataSize) { receivedData = Encoding.Unicode.GetString(await receiveData(dataSize)); //await saveClientCommand(cCom); }
//information processing, server-client communication private async Task handleMessage(Commands.ClientCommands cCom, int dataSize) { Console.WriteLine("Handling message ({0})...", cCom); switch (cCom) { case Commands.ClientCommands.RequestCompareVersionNumber: Console.WriteLine("Comparing version number..."); await receiveString(cCom, dataSize); Console.WriteLine("String received. {0} vs {1}", VersionNumber.get(), (string)receivedData); if (VersionNumber.get() == (string)receivedData) { await sendCommand(Commands.ServerCommands.ValidVersionNumber); Console.WriteLine("Reply sent: valid."); } else { await sendCommand(Commands.ServerCommands.InvalidVersionNumber); Console.WriteLine("Reply sent: invalid."); } return; case Commands.ClientCommands.SubmitUserName: Console.Write("Checking submitted username... "); await receiveString(cCom, dataSize); username = ""; if (parentServer.getOnlineUsers().Contains((string)receivedData)) //the user going by this name is already logged in -> choose different name { await sendCommand(Commands.ServerCommands.UserAlreadyOnline); Console.WriteLine("Already online."); } else if (parentServer.getRegisteredUsers().Contains((string)receivedData)) //submitted name contained in the list of registered users? { await sendCommand(Commands.ServerCommands.UserNameFound); Console.WriteLine("Found."); } else { await sendCommand(Commands.ServerCommands.UserNameNotFound); Console.WriteLine("Not found."); } username = (string)receivedData; Console.WriteLine("username set to {0}.", username); return; case Commands.ClientCommands.SubmitPassword_ExistingUser: await receiveString(cCom, dataSize); //Console.WriteLine("Checking password ({0} | {1})...", username, (string)receivedData); if (parentServer.tryLogin(username, (string)receivedData)) { await sendCommand(Commands.ServerCommands.LoginSuccessful); await goOnline(); //sets online to true and updates all lbUser listboxes parentServer.addSystemMessage($"{username} has come online."); } else { await sendCommand(Commands.ServerCommands.PasswordIncorrect); username = ""; } break; case Commands.ClientCommands.SubmitPassword_NewUser: await receiveString(cCom, dataSize); //Console.WriteLine("Creating new user ({0} | {1})...", username, (string)receivedData); if (parentServer.tryRegister(username, (string)receivedData)) { await sendCommand(Commands.ServerCommands.AccountCreatedSuccessfully); await goOnline(); //sets online to true and updates all lbUser listboxes parentServer.addSystemMessage($"{username} has created their account and is now online for the first time."); } else { await sendCommand(Commands.ServerCommands.ServerError); username = ""; } break; case Commands.ClientCommands.RequestOnlineUserList: Console.WriteLine("Sending user list..."); await sendObject(Commands.ServerCommands.ReceiveList_String, parentServer.getOnlineUsers()); break; case Commands.ClientCommands.RequestSendMessage: Console.WriteLine("Sending message..."); await receiveObject(Commands.ClientCommands.RequestSendMessage, dataSize); ChatMessage recMsg = (ChatMessage)receivedData; if (await parentServer.sendMessage(recMsg)) { await sendCommand(Commands.ServerCommands.MessageSent); } else { await sendCommand(Commands.ServerCommands.ServerError); } break; default: Console.WriteLine("Unhandled client command ({0}).", cCom); break; } return; }