diff --git a/MySolution/STcpHelper/Packet/PacketType.cs b/MySolution/STcpHelper/Packet/PacketType.cs index 163bd43..709510b 100644 --- a/MySolution/STcpHelper/Packet/PacketType.cs +++ b/MySolution/STcpHelper/Packet/PacketType.cs @@ -9,6 +9,7 @@ namespace STcpHelper.Packet public enum PacketType { TEXT = 0, - + REQ_CLIENT_LIST, + RES_CLIENT_LIST, } } diff --git a/MySolution/STcpHelper/Packet/SBufferHelper.cs b/MySolution/STcpHelper/Packet/SBufferHelper.cs index 875631b..9c9c7a3 100644 --- a/MySolution/STcpHelper/Packet/SBufferHelper.cs +++ b/MySolution/STcpHelper/Packet/SBufferHelper.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace STcpHelper.Packet { - static class SBufferHelper + internal class SBufferHelper { public static byte[] GetBuffer(int size, params byte[][] args) { diff --git a/MySolution/STcpHelper/Packet/SEncoding.cs b/MySolution/STcpHelper/Packet/SEncoding.cs new file mode 100644 index 0000000..c251132 --- /dev/null +++ b/MySolution/STcpHelper/Packet/SEncoding.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace STcpHelper.Packet +{ + internal class SEncoding + { + public static string GetString(byte[] bytes, int index, int length) + { + return Encoding.UTF8.GetString(bytes, index, length); + } + + public static byte[] GetBytes(string s) + { + return Encoding.UTF8.GetBytes(s); + } + } +} diff --git a/MySolution/STcpHelper/Packet/STcpClientListReqPacket.cs b/MySolution/STcpHelper/Packet/STcpClientListReqPacket.cs new file mode 100644 index 0000000..1344564 --- /dev/null +++ b/MySolution/STcpHelper/Packet/STcpClientListReqPacket.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace STcpHelper.Packet +{ + public class STcpClientListReqPacket : ISTcpPacket + { + public STcpClientListReqPacket() + { + + } + + public byte[] Serialize() + { + // 4bytes header + STcpPacketHeader header = new STcpPacketHeader(PacketType.REQ_CLIENT_LIST, 0); + + // [header] + return SBufferHelper.GetBuffer(4, header.Serialize()); + } + } +} diff --git a/MySolution/STcpHelper/Packet/STcpClientListResPacket.cs b/MySolution/STcpHelper/Packet/STcpClientListResPacket.cs new file mode 100644 index 0000000..674a105 --- /dev/null +++ b/MySolution/STcpHelper/Packet/STcpClientListResPacket.cs @@ -0,0 +1,51 @@ +using STcpHelper.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace STcpHelper.Packet +{ + public class STcpClientListResPacket : ISTcpPacket + { + public List Clients { get; private set; } + + public STcpClientListResPacket(List clinets) + { + this.Clients = new List(); + foreach (var client in clinets) + { + this.Clients.Add(client.Client.RemoteEndPoint.ToString()); + } + } + + public STcpClientListResPacket(byte[] dataBuffer) + { + int cursor = 0; + short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor)); + cursor += sizeof(short); + + string jsonString = SEncoding.GetString(dataBuffer, cursor, length); + List clients = JsonSerializer.Deserialize>(jsonString); + + this.Clients = clients; + } + + public byte[] Serialize() + { + string jsonString = JsonSerializer.Serialize(this.Clients); + byte[] data = SEncoding.GetBytes(jsonString); + byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length)); + + // 4bytes header + STcpPacketHeader header = new STcpPacketHeader(PacketType.RES_CLIENT_LIST, dataLength.Length + data.Length); + + // [header][2bytes size][n bytes string] + return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data); + } + } +} diff --git a/MySolution/STcpHelper/Packet/STcpTextPacket.cs b/MySolution/STcpHelper/Packet/STcpTextPacket.cs index 9faa8d7..46c60c3 100644 --- a/MySolution/STcpHelper/Packet/STcpTextPacket.cs +++ b/MySolution/STcpHelper/Packet/STcpTextPacket.cs @@ -19,22 +19,22 @@ namespace STcpHelper.Packet public STcpTextPacket(byte[] dataBuffer) { int cursor = 0; - short textSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor)); + short length = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer, cursor)); cursor += sizeof(short); - this.Text = Encoding.UTF8.GetString(dataBuffer, cursor, textSize); + this.Text = SEncoding.GetString(dataBuffer, cursor, length); } public byte[] Serialize() { - byte[] text = Encoding.UTF8.GetBytes(Text); - byte[] textSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)text.Length)); + byte[] data = SEncoding.GetBytes(Text); + byte[] dataLength = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)data.Length)); - // 4byte header - STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, text.Length + textSize.Length); + // 4bytes header + STcpPacketHeader header = new STcpPacketHeader(PacketType.TEXT, dataLength.Length + data.Length); - // [2bytes text size][n bytes text] - return SBufferHelper.GetBuffer(4 + textSize.Length + text.Length, header.Serialize(), textSize, text); + // [header][2bytes text size][n bytes text] + return SBufferHelper.GetBuffer(4 + dataLength.Length + data.Length, header.Serialize(), dataLength, data); } } } diff --git a/MySolution/STcpHelper/Packet/SXmlSerializerHelper.cs b/MySolution/STcpHelper/Packet/SXmlSerializerHelper.cs new file mode 100644 index 0000000..cec02ec --- /dev/null +++ b/MySolution/STcpHelper/Packet/SXmlSerializerHelper.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace STcpHelper.Packet +{ + static class SXmlSerializerHelper + { + public static string Serialize(T obj) + { + XmlSerializer serializer = new XmlSerializer(typeof(T)); + using (StringWriter sw = new StringWriter()) + { + serializer.Serialize(sw, obj); + return sw.ToString(); + } + } + + public static T Deserialize(string str) + { + XmlSerializer serializer = new XmlSerializer(typeof(T)); + using (StringReader sr = new StringReader(str)) + { + return (T)serializer.Deserialize(sr); + } + } + } +} diff --git a/MySolution/STcpHelper/STcpClient.cs b/MySolution/STcpHelper/STcpClient.cs index fcb414e..d52a221 100644 --- a/MySolution/STcpHelper/STcpClient.cs +++ b/MySolution/STcpHelper/STcpClient.cs @@ -62,6 +62,14 @@ namespace STcpHelper STcpTextPacket packet = new STcpTextPacket(dataBuffer); WriteMessage(packet.Text); } + else if (header.Type == PacketType.RES_CLIENT_LIST) + { + STcpClientListResPacket packet = new STcpClientListResPacket(dataBuffer); + foreach (var client in packet.Clients) + { + WriteMessage(client); + } + } } }, _cts.Token); } @@ -90,6 +98,19 @@ namespace STcpHelper } } + public async void RequireClientList() + { + try + { + STcpClientListReqPacket packet = new STcpClientListReqPacket(); + await _stream.WriteAsync(packet.Serialize()); + } + catch (Exception ex) + { + WriteError(ex); + } + } + public void Close() { try diff --git a/MySolution/STcpHelper/STcpServer.cs b/MySolution/STcpHelper/STcpServer.cs index 0a794f6..f0d13a6 100644 --- a/MySolution/STcpHelper/STcpServer.cs +++ b/MySolution/STcpHelper/STcpServer.cs @@ -80,6 +80,14 @@ namespace STcpHelper BroadcastMessage(packet.Text, client); } + else if (header.Type == PacketType.REQ_CLIENT_LIST) + { + STcpClientListResPacket packet = new STcpClientListResPacket(_clients); + WriteMessage($"[{client.Client.RemoteEndPoint.ToString()}] Type: {header.Type.ToString()}"); + + // Send + SendPacket(packet, client); + } if (!IsClientConnected(client)) break; @@ -109,6 +117,15 @@ namespace STcpHelper return packet.Serialize(); } + private void SendPacket(ISTcpPacket packet, TcpClient requester) + { + byte[] responseByte = packet.Serialize(); + if (!IsClientConnected(requester)) + return; + + requester.GetStream().WriteAsync(responseByte, 0, responseByte.Length); + } + private void BroadcastMessage(string message, TcpClient sender) { byte[] resonseByte = MakeTextPacket(message); diff --git a/MySolution/TAPClient/Program.cs b/MySolution/TAPClient/Program.cs index 9a93e79..c1cf4be 100644 --- a/MySolution/TAPClient/Program.cs +++ b/MySolution/TAPClient/Program.cs @@ -13,8 +13,17 @@ namespace TAPClient while (true) { - string message = Console.ReadLine(); - client.SendMessage(message); + string input = Console.ReadLine(); + switch (input.ToLower()) + { + case "rcl": + client.RequireClientList(); + break; + default: + client.SendMessage(input); + break; + } + } } }