using Core; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace Client { internal class Singleton { public static Singleton Instance { get; set; } = new Singleton(); public string Id { get; set; } = ""; public string Nickname { get; set; } = ""; public Socket Socket { get; } = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public event EventHandler? LoginResponsed; public event EventHandler? CreateRoomResponsed; public event EventHandler? RoomListResponsed; public event EventHandler? EnterRoomResponsed; public async Task ConnectAsync(string ip, int port) { IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port); await this.Socket.ConnectAsync(endPoint); ThreadPool.QueueUserWorkItem(ReceiveAsync, this.Socket); } public async Task SendAsync(byte[] buffer, SocketFlags socketFlags) { return await this.Socket.SendAsync(buffer, socketFlags); } private async void ReceiveAsync(object? sender) { if (sender == null) return; Socket socket = (Socket)sender; byte[] headerBuffer = new byte[2]; while (true) { // header buffer int n1 = await socket.ReceiveAsync(headerBuffer, SocketFlags.None); if (n1 < 1) { Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}"); socket.Dispose(); return; } else if (n1 == 1) { await socket.ReceiveAsync(new ArraySegment(headerBuffer, 1, 1), SocketFlags.None); } // data buffer short dataSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBuffer)); byte[] dataBuffer = new byte[dataSize]; int totalRecv = 0; while (totalRecv < dataSize) { int n2 = await socket.ReceiveAsync(new ArraySegment(dataBuffer, totalRecv, dataSize - totalRecv), SocketFlags.None); totalRecv += n2; } PacketType packetType = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer)); if (packetType == PacketType.LoginResponse) { LoginResponsePacket packet = new LoginResponsePacket(dataBuffer); LoginResponsed?.Invoke(packet, EventArgs.Empty); } else if (packetType == PacketType.CreateRoomResponse) { CreateRoomResponsePacket packet = new CreateRoomResponsePacket(dataBuffer); CreateRoomResponsed?.Invoke(packet, EventArgs.Empty); } else if (packetType == PacketType.RoomListResponse) { RoomListResponsePacket packet = new RoomListResponsePacket(dataBuffer); RoomListResponsed?.Invoke(packet, EventArgs.Empty); } else if (packetType == PacketType.EnterRoomResponse) { EnterRoomResponsePacket packet = new EnterRoomResponsePacket(dataBuffer); EnterRoomResponsed?.Invoke(packet, EventArgs.Empty); } } } } }