using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using UdpClientLib; using UnityEngine; public class SingleTcpClient : NetworkClientBase { private NetworkStream stream; private System.Net.Sockets.TcpClient client; private bool isConnected = false; private readonly SemaphoreSlim requestSemaphore = new SemaphoreSlim(1, 1); public async Task ConnectAsync(string name, string serverIp, int serverPort, int? localPort = null) { try { Name = name; _serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), serverPort); client = new System.Net.Sockets.TcpClient(); await client.ConnectAsync(serverIp, serverPort); stream = client.GetStream(); isConnected = true; Console.WriteLine($"TCP 서버에 연결되었습니다: {serverIp}:{serverPort}"); return true; } catch (Exception ex) { Console.WriteLine($"연결 실패: {ex.Message}"); return false; } } public async Task SendMessageAsync(string message) { if (!isConnected || stream == null) { Console.WriteLine("서버에 연결되지 않았습니다."); return false; } try { byte[] data = Encoding.UTF8.GetBytes(message); await stream.WriteAsync(data, 0, data.Length); Console.WriteLine($"메시지 전송: {message}"); return true; } catch (Exception ex) { Console.WriteLine($"메시지 전송 실패: {ex.Message}"); return false; } } public async Task ReceiveMessageAsync() { if (!isConnected || stream == null) { Console.WriteLine("서버에 연결되지 않았습니다."); return null; } try { byte[] buffer = new byte[4096]; int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) { Console.WriteLine("서버와의 연결이 끊어졌습니다."); return null; } string message = Encoding.UTF8.GetString(buffer, 0, bytesRead); return message; } catch (Exception ex) { Console.WriteLine($"메시지 수신 실패: {ex.Message}"); return null; } } public void Disconnect() { try { isConnected = false; stream?.Close(); client?.Close(); Console.WriteLine("서버와의 연결을 종료했습니다."); } catch (Exception ex) { Console.WriteLine($"연결 종료 중 오류: {ex.Message}"); } } public async Task SendHttpRequestAsync(HttpRequest request) { //await requestSemaphore.WaitAsync(); try { string httpPacket = CreateHttpRequest(request); await SendMessageAsync(httpPacket); return await ReceiveMessageAsync(); } finally { // requestSemaphore.Release(); } } // 편의 메서드들 public Task SendGetRequestAsync(string path, Dictionary headers = null) => SendHttpRequestAsync(new HttpRequest(UdpClientLib.HttpMethod.GET, path, headers)); public Task SendPostRequestAsync(string path, object body = null, Dictionary headers = null) { string jsonBody; if (body == null) { jsonBody = null; } else if (body is string str) { jsonBody = str; } else { jsonBody = JsonConvert.SerializeObject(body); } return SendHttpRequestAsync(new HttpRequest(UdpClientLib.HttpMethod.POST, path, headers, jsonBody)); } public bool IsConnected => isConnected && client?.Connected == true; }