Files
HDRobotics/Assets/Scripts/Network/SingleTcpClient.cs

159 lines
4.2 KiB
C#
Raw Normal View History

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<bool> 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<bool> 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<string> 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<String> SendHttpRequestAsync(HttpRequest request)
{
//await requestSemaphore.WaitAsync();
try
{
string httpPacket = CreateHttpRequest(request);
await SendMessageAsync(httpPacket);
return await ReceiveMessageAsync();
}
finally
{
// requestSemaphore.Release();
}
}
// 편의 메서드들
2025-11-19 18:38:48 +09:00
public Task<String> SendGetRequestAsync(string path, Dictionary<string, string> headers = null, CancellationToken token = default)
=> SendHttpRequestAsync(new HttpRequest(UdpClientLib.HttpMethod.GET, path, headers, null, token));
2025-11-19 18:38:48 +09:00
public Task<String> SendPostRequestAsync(string path, object body = null, Dictionary<string, string> headers = null, CancellationToken token = default)
{
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;
}