포트포워딩이 제대로 된 것을 확인했으니, 클라이언트와 서버를 각각 빌드하여 통신이 제대로 되는지 확인해야 합니다. 그러기 위해서, 우선 간단한 통신을 할 수 있는 코드를 짜보겠습니다.
public class ClientManager
{
public void SendMessage()
{
_ = Task.Run(() => SendMessageAsync());
}
int number = 0;
private async void SendMessageAsync()
{
TcpClient client = new TcpClient(Constants.IP_ADDR_INHO, Constants.PORT_VM_TCP);
NetworkStream stream = client.GetStream();
string data = "HELLO SERVER!" + number++;
byte[] buffer = Encoding.UTF8.GetBytes(data);
await stream.WriteAsync(buffer, 0, buffer.Length);
await stream.FlushAsync();
buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Debug.Log("RESPONSE : " + response);
client.Close();
}
간단하게 string을 주고 받는 클라이언트입니다.
TCP 통신은 byte stream으로 이루어지기 때문에, 더 복잡한 데이터를 주고받기 위해서는 직렬화 과정이 필요합니다.
public class ServerManager : MonoBehaviour
{
//
// other funcs...
//
private async void StartServer()
{
TcpListener listener = new TcpListener(IPAddress.Any, Constants.PORT_VM_TCP);
listener.Start();
while (true)
{
TcpClient client = await listener.AcceptTcpClientAsync();
DebugServer.Log("ClientConnected");
_ = Task.Run(() => HandleClient(client));
}
}
private async void HandleClient(TcpClient client)
{
try
{
byte[] buffer = new byte[1024];
int bytesRead;
Stream stream = client.GetStream();
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
DebugServer.Log("Received: " + data);
string result = await RunSimulation();
byte[] sendBuff = Encoding.UTF8.GetBytes(result);
await stream.WriteAsync(sendBuff, 0, sendBuff.Length);
DebugServer.Log("Transmit: " + result);
}
}
catch(Exception ex)
{
DebugServer.Log($"Client Error : {ex.Message}");
}
finally
{
client.Close();
}
}
private async Task<String> RunSimulation()
{
await Task.Delay(4000); // HACK - 4초 딜레이
return "Hello Client!";
}
}
Server도 간단한 Iterative Echo Server 입니다.
저는 Headless 로 Simulation을 돌리는게 목적이기 때문에 RunSimulation 함수에서 4초 정도의 딜레이를 주고 테스트 해보았습니다.

새로운 씬을 만들고, StartServer 를 호출하게 만든 후에 빌드를 진행했습니다.
해당 빌드파일은 VMWare 의 SharedFolder 기능을 사용하여 전송했습니다.


비동기적으로 잘 처리되는 모습을 확인하실 수 있습니다.
간단한 string을 서버에서 비동기적으로 처리하여 여러 요청을 동시에 받을 수 있도록 해보았습니다.
이제 보내는 데이터를 구조체로 바꾸고 직렬화하여 바이트 스트림으로 보낼 수 있도록 하겠습니다.