[03]과 이어집니다.
serverSocket.Bind(endPoint);
을 사용해서 serverSocket과 endPoint를 연결해줍시다.
이제 [03]에서 말했던 서버의 Socket -> Bind -> listen -> accept -> receive -> send -> receive -> close 과정에서 Bind까지를 끝냈습니다. Listen 메소드를 만들어봅시다.
private void ListenSocket()
{
serverSocket.Listen(5); // 대기 큐 크기를 지정
Console.WriteLine("Server started. Waiting for connections...");
Socket clientSocket = serverSocket.Accept();
}
Listen은 만들어진 서버인 serverSocket을 클라이언트를 받아들일 수 있는 상태로 만듭니다. (5)라는 인수는 대기 큐 크기로, 최대 5명까지의 접속을 큐에 넣을 수 있게 해 줍니다. 그 다음으로 클라이언트의 접속을 기다려, 서버에 집어넣습니다.
여기까지가 Client가 관여하지 않은, 서버에서만 준비과정으로 실행되는 것입니다. 지금까지의 코드를 정리해봅시다.
private Socket serverSocket;
private Socket clientSocket;
private IPAddress ipaddress;
private string ipaddressStr;
private int port;
private IPEndPoint endpoint;
//Socket -> Bind -> listen -> accept -> receive -> send -> receive -> close
//Creat Socket
public void StartServer()
{
//서버 소켓 생성
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//IP 주소와 포트 설정. 그리고 바인드
SetIPAndBind(ipaddressStr, port);
//Listen, 클라이언트 대기.
ListenSocket();
}
// IP 주소와 포트 설정 + Bind. Socekt을 ipaddress와 port를 사용해서 바인딩
public void SetIPAndBind(string ipAddressStr, int port)
{
ipaddress = IPAddress.Parse(ipAddressStr);
endpoint = new IPEndPoint(ipaddress, port);
serverSocket.Bind(endpoint);
}
//listen, 클라이언트를 기다린다.
private void ListenSocket()
{
serverSocket.Listen(5); // 대기 큐 크기를 지정
Console.WriteLine("Server started. Waiting for connections...");
clientSocket = serverSocket.Accept();
}
그런데, 여기서 마지막 부분인 clientSocket = serverSocket.Accept();에 문제가 있습니다.
바로 한 클라이언트만 선언이 되어있기 때문에, 이대로 실행한다면 여러 사용자를 받지 못한다는 점입니다.
당연히 여러 사람이 동시에 통신하기를 원하므로 수정되어야 합니다. 가장 간단한 방법은 클라이언트 개수만큼 서버가 소켓을 만들어줘서 1:1 통신을 여러번 하는 것이지만, 사용자가 많아질수록 서버 부하가 커지기 때문에, Thread를 사용하는 방식으로 진행하겠습니다. (또, 각 클라이언트에 대한 작업을 순차적으로 실행하여 동시에 안됨)
즉 고쳐야 할 것은 clientSocket의 접속을 받아서 처리하는 곳. 이 부분을 Thread가 컨트롤할 수 있도록 보내버리자. 코드는 아래와 같다.
using System.Threading;
먼저 Thread를 C#에서 지원해주는 System.Threading을 입력하고...
public void StartServer()
{
//서버 소켓 생성
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//IP 주소와 포트 설정. 그리고 바인드
SetIPAndBind(ipaddressStr, port);
//Listen, 클라이언트 연결 요청 대기.
ListenSocket();
while (true)
{
Socket clientSocket = serverSocket.Accept();
Console.WriteLine("새 사용자 접속!");
Thread clientThread = new Thread(() => HandleClient(clientSocket));
clientThread.Start();
}
}
기존의 StartServer에서 변경된 부분은 ListenSocket()이후.
대기상태에서 계속해서 들어오는 클라이언트를 쓰레드로 보내서 HandleClient라는 함수를 실행시키고, 쓰레드를 시작한다. 이제 클라이언트의 작업은 쓰레드에서 실행될 것이다. (여기서 clientSocket은 재선언되어야한다.)
그럼, HandleClient라는 함수를 살펴봐야한다. 쓰레드 안에서 실행되는 이 함수의 내용을 뜯어보자.
HandleClient(Socket clientSocket)
우선 clientSocket. 이 소켓은 Accept,(나중에 BeginAccept 등으로 변경될 여지가 있음)으로 서버에 연결된 클라이언트 소켓을 뜻한다. 이 소켓과 서버의 소켓이 서로 데이터를 주고 받는 과정을 HandleClient에서 다룰 예정이다.
'IndianPoker' 카테고리의 다른 글
[06] TCP, 클라이언트 만들기 (1) | 2023.10.28 |
---|---|
[05] Thread, Handle Client (1) | 2023.10.28 |
[03] TCP 소켓 준비, Input Field와 UI (0) | 2023.10.26 |
[01-02] 홈과 로딩에 대해 (0) | 2023.10.24 |
[00] 초기 기획 및 구상 (0) | 2023.10.24 |