본문 바로가기
게임 서버/네트워크

[c#/네트워크] 소켓 프로그래밍

by 얘리밍 2022. 12. 12.
320x100
728x90

 

 

 

소켓 프로그래밍을 구현해 보겠다. 

 

 

다음과 같이 파일 구조를 만든다..

 

 

그 다음 솔루션 우클릭 후, 속성에 들어가서 

클라이언트와 서버가 한 번에 실행되도록 다음과 같이 설정한다. 

 

 

 


 

 

 

 

 

이제 서버부터 구현해 보자.

일단 연결을 시도하려는 자에 대한 정보를 얻어야 한다.

 

 //DNS (Domain Name System)
 //도메인 등록 후 -> IP주소 찾게끔 만들면 유지보수가 용이함
 //PC의 호스트명을 받는다 (호스트명은 IP 주소 대신 사용할 수 있는 식별 이름) 
string host = Dns.GetHostName();    


IPHostEntry ipHost = Dns.GetHostEntry(host);  //해당 호스트의 IP 관련 주소들을 받는다. 
IPAddress ipAddr = ipHost.AddressList[0];   //여러개의 주소를 담고있는 리스트를 반환하며 이중 첫번째 값을 할당한다(여러개의 주소를 뱉어주는 경우도 있음) 
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);  //7777은 포트 번호 , IP 주소와 포트 번호를 할당한다.

 

  • IPHostEntry : DNS 클래스의 GetHostEntry의 반환 값을 담는 컨테이너 클래스. 호스트 관련 정보와 IP관련 정보를 받는다.
  • IPAddress : 하나의 인터페이스에 대한 주소를 포함하는 클래스. 첫번 째 인덱스에 담긴 IP 주소를 할당한다.
  • IPEndPoint : IP 주소와 포트를 바인딩하여 소켓과 원격 주소를 연결한다. 

 

 

 

 

 

서버 코드 

 

    //문지기 
    Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try{

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


        // 영업 시작
        // backlog : 최대 대기수
        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.Write(e.ToString());
    }
  1. 문지기를 만든다 -> 서버 소켓을 만든다 (IP관련 정보와 소켓 타입, 연결 방법(프로토콜 설정)을 결정한다. 
  2. endPoint를 바인드 한다 (* endPoint : IP주소와 포트 번호의 조합)
  3. 클라이언트를 입장 시키고, 클라이언트가 전달하려는 내용을 받는다. (문자열을 전달하는 간단 예제)
  4. 클라이언트에게 서버 응답을 전달한다 
  5. 후 연결을 종료한다                                                                                                                                                                   (* shut down : 현재 연결된 프로세스의 개수에 상관없이 연결을 종료한다. close: 연결된 개수가 0이 되어야지만 연결이 종료된다. 소켓을 메모리 상에서 완전 해제하려면 shutdown 후에 close를 해 줘야 한다)

 

 

 

 

 

⭐ 클라이언트 코드

 

    //클라이언트 소켓 설정 
    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("Connected Client !");
        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.Write(e.ToString);
    }

 

 

실행 화면

 

서버 실행 화면

 

 

클라이언트 실행 화면

 

 

 

출처 : https://www.inflearn.com/course/유니티-mmorpg-개발-part4

728x90
반응형