C#/네트워크

[c#][서버] 소켓 프로그래밍

goliot 2024. 6. 5. 15:37
반응형

소켓 통신의 개념 흐름

고오급 식당

  • 입구마련, 문지기 고용
  • 문자기 교육
    • 식당 이름, 연락처, 입구의 정보
    • 가게 폰 하나 쥐어주고 대기시킴
  • 식당 오픈
  • 손님 입장
    • 식당에 연락해둠
    • 문지기는 대리인을 앉히고, 손님과 연락하게 함실제 컴퓨터
  • 손님
    • 소켓 준비
    • 서버 주소로 Connect
    • 소켓을 통해 Session 소켓과 패킷 송수신 가능
  • 식당
    • Listener 소켓 준비
    • Bind(서버 주소 / Port를 소켓에 연동)
    • Listen
    • Accept
    • 클라이언트 세션을 통해 손님과 통신

구현

  • 서버 측
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ServerCore
{
    class Program
    {
        static void Main(string[] args)
        {
            //DNS 사용
            string host = Dns.GetHostName(); //내 로컬 컴퓨터의 호스트 이름
            IPHostEntry ipHost = Dns.GetHostEntry(host);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); //주소, 포트번호

            //문지기
            Socket listenSocket = new Socket(
                endPoint.AddressFamily,
                SocketType.Stream, 
                ProtocolType.Tcp
            );//TCP 프로토콜 사용

            try
            {
                //문지기 교육
                listenSocket.Bind(endPoint);

                //영업 시작
                listenSocket.Listen(10); //파라미터: 최대 대기자 수

                while (true) //계속 켜져있어야 하니까 무한루프
                {
                    Console.WriteLine("Listening...");

                    //손님 입장
                    Socket clientSocket = listenSocket.Accept();
                    //블로킹 함수 -> 클라이언트가 입장하지 않으면, 아랫줄로 넘어가지 않음

                    //받는다
                    byte[] recvBuff = new byte[1024];
                    int recvBytes = clientSocket.Receive(recvBuff);
                    string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes); //숫자는 시작 인덱스
                    Console.WriteLine($"[From Client] {recvData}");

                    //보낸다
                    byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to MMORPG Server!");
                    clientSocket.Send(sendBuff);
                    //얘도 상대방이 받지 않으면 대기

                    //쫓아낸다
                    clientSocket.Shutdown(SocketShutdown.Both); //쫓아낼 것 예고
                    clientSocket.Close(); //쫓아내기
                }
            }
            catch ( Exception e ) 
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}
  • 클라이언트 측
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace DummyClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //DNS 사용
            string host = Dns.GetHostName(); //내 로컬 컴퓨터의 호스트 이름
            IPHostEntry ipHost = Dns.GetHostEntry(host);
            IPAddress ipAddr = ipHost.AddressList[0];
            IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); //주소, 포트번호

            //손님 휴대폰 설정
            Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                //문지기한테 입장 문의
                socket.Connect(endPoint);
                Console.WriteLine($"Connected To {socket.RemoteEndPoint.ToString()}");

                //보낸다
                byte[] sendBuff = Encoding.UTF8.GetBytes("Hello world!");
                int sendBytes = socket.Send(sendBuff);

                //받는다
                byte[] recvBuff = new byte[1024];
                int recvBytes = socket.Receive(recvBuff);
                string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
                Console.WriteLine($"[From Server] {recvData}");

                //나간다
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    }
}
  • 실행 결과 -> 두 코드를 함께 실행시켜야 한다

클라이언트측은 메시지를 받고 종료, 서버측은 계속 다음 클라이언트를 기다림

  • 주의할 점
    • 실제 게임에서는 , Send, Receive같은 블로킹 함수를 쓰면 안됨
    • 그러면, 송신이나 수신이 이뤄지지 않았을 때, 무한 대기하는 현상이 나타남

 

반응형

'C# > 네트워크' 카테고리의 다른 글

[c#][서버] Session  (1) 2024.06.06
[c#][서버] Listener  (0) 2024.06.05
[c#][서버] 네트워크 기초 이론  (0) 2024.06.04
[c#][서버] Thread Local Storage  (0) 2024.06.03
[c#][서버] ReaderWriterLock  (0) 2024.06.03