TCPClientSync.cs(클라이언트)
1.TcpClient를 사용하여 서버에 연결합니다.
2.사용자가 입력한 텍스트 메시지를 서버에 보냅니다.
3.서버로부터 에코된 메시지를 받아 화면에 표시합니다.
- ConnectToServer()를 Start()에서 바로 호출
- ReceiveMessages()를 ConnectToServer()가 성공한 직후 바로 호출하여 메인 스레드에서 계속해서 메시지를 수신
- 또는 Update()에서 주기적으로 호출하는 방식으로 변경할 수도 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Net.Sockets;
using System.Text;
public class TcpClientSync : MonoBehaviour
{
//접속할 TCP 서버의 IP주소와 포트번호
[SerializeField] private string serverIP = "127.0.0.1"; //localhost IP //192.168.0.0.1
[SerializeField] private int serverPort = 8888;
[SerializeField] private InputField inputField;
[SerializeField] private Button sendButton;
[SerializeField] private Text responseText; //또는 TextMeshProUGUI
private TcpClient tcpClient;
private NetworkStream stream;
// Start is called before the first frame update
void Start()
{
if (inputField == null || sendButton == null || responseText == null)
{
Debug.LogError("UI Error");
return;
}
//UI가 준비되지 않은 경우 이하는 실행되지 않음.
sendButton.onClick.AddListener(SendData); //버튼 누르면 SendData() 호출
ConnectToServer();
}
void ConnectToServer()
{
try
{
tcpClient = new TcpClient(serverIP, serverPort); //지정한 IP,포트로 TCP 연결.
stream = tcpClient.GetStream(); //NetworkStream을 얻어 통신 준비
responseText.text = "Connect to server";
Debug.Log("Connected to server");
SendData();
ReceiveMessages();
}
catch (Exception e)
{
Debug.LogError("Connection error :" + e.Message);
responseText.text = "Connection Failed..";
}
}
void SendData()
{
if (tcpClient == null || !tcpClient.Connected)
{
Debug.LogError("Not connected to server.");
responseText.text = "Not Connected";
return;
}
if (inputField.text == null) inputField.text = "hi";
string message = inputField.text;
if (string.IsNullOrEmpty(message))
{
Debug.LogError("Input is empty!");
return;
}
byte[] data = Encoding.UTF8.GetBytes(message); //인풋필드의 텍스트를 UTF-8로 인코딩
try
{
stream.Write(data, 0, data.Length); //NetworkStream을 통해 서버로 전송
Debug.Log("sent:" + message);
inputField.text = ""; //입력창 비우기
}
catch (Exception e)
{
Debug.LogError("Send error :" + e.Message);
responseText.text = "send error";
}
}
void ReceiveMessages()
{
byte[] buffer = new byte[1024];
int byteRead;
// 서버 연결이 종료되면 루프 종료
while (tcpClient != null && tcpClient.Connected)
{
try
{
byteRead = stream.Read(buffer, 0, buffer.Length); //서버에서 데이터가 도착할 때까지 대기하므로 blocking 발생가능
if (byteRead == 0)
{
Debug.Log("server disconnected");
responseText.text = "serverIP disconnected";
break;
}
string receiveMessage = Encoding.UTF8.GetString(buffer, 0, byteRead);
responseText.text = "server :" + receiveMessage; //Text로 출력
Debug.Log("received :" + receiveMessage);
}
catch (Exception e)
{
if (e is SocketException || e is ObjectDisposedException)
{
Debug.Log("Server disconnected");
}
else
{
Debug.LogError("Receive Error :" + e.Message);
}
responseText.text = "Receive error";
break;
}
}
}
void OnDestroy()
{
if (stream != null)
{
stream.Close();
}
if (tcpClient != null)
{
tcpClient.Close();
}
}
}
tcpClient = new TcpClient(serverIP, serverPort)
지정한 IP와 포트로 연결하는 TCP 클라이언트를 생성한다.
.Read(buffer, 0, buffer.Length)
NetworkStream.Read() 메서드는 동기(Blocking) 메서드이다. 즉, 다음 중 하나가 일어날 때까지 실행이 중단(Block) 된다:
- 지정된 buffer.Length만큼 데이터를 수신했을 때
- 상대방이 연결을 종료해서 더 이상 읽을 수 없게 되었을 때
- 내부적으로 설정된 타임아웃이 발생했을 때 (타임아웃이 설정되어 있는 경우에만)
Encoding.UTF8.GetBytes(message)
- 문자열 message를 UTF-8 바이트 배열로 인코딩하여 저장한다.
- 네트워크 전송이나 파일 저장 등에서 문자열을 바이트 단위로 처리할 필요가 있을 때 사용한다.
Encoding.UTF8.GetString(buffer, 0, byteRead)
- buffer에 담긴 바이트 데이터를 UTF-8로 해석하여 사람이 읽을 수 있는 문자열로 변환한다.
- 주로 네트워크에서 수신한 데이터를 처리할 때 사용된다.
클라이언트(Unity Editor에서)의 UI 구성
1.InputField: 메시지 입력을 위한 UI 요소.
2.Button: 메시지 전송 버튼.
3.Text(또는TextMeshPro-Text): 서버 응답을 표시할 텍스트 UI 요소.
TCPClientSync 스크립트를 빈 GameObject에 추가하여 활성화하고, Inspector창에서 구성된 UI를 연결한다.
주의할 점
UI 멈춤:클라이언트에서 연결, 전송, 수신 작업이 진행되는 동안 UI가 멈출 수 있다. 특히 서버가 느리거나 네트워크 연결이 불안정하면 멈춤 현상이 더 심해질 수 있다.
제한적인 사용:이 동기 방식은 매우 간단한 테스트나 학습 목적으로만 사용하는 것이 좋다. 실제 게임이나 애플리케이션에서는 반드시 비동기 방식(async/await, 스레드, 코루틴 등)을 사용하여 UI 멈춤을 방지해야 한다
'UNITY > 네트워크' 카테고리의 다른 글
[네트워크] TCP/IP - 비동기 방식의 연결 (1)TCP 비동기 서버 (0) | 2025.06.12 |
---|---|
[네트워크] TCP/IP 비동기 통신 함수 (0) | 2025.06.12 |
[네트워크] 비동기 통신 (0) | 2025.06.11 |
[네트워크] TCP/IP - 동기형 방식의 연결 (1)TCP 동기형 서버 (0) | 2025.05.30 |
[네트워크] TCP/IP 동기 통신 함수 (0) | 2025.03.03 |