C#_UDP Server / Client

Today Jeeho Learned·2022년 11월 25일
0

C#

목록 보기
12/17

UDP Server

UDP 서버는 포트를 열고, client로부터 들어오는 데이터그램을 수신하게 된다. UDP 서버는 통상 UDP 포트를 Listening하고 있으면서 루프 안에서 계속 데이터 송수신을 처리하는 형태로 구현된다. TCP 서버는 TCP 클라이언트 연결을 받아들여 Connetion을 맺은 후에 데이터 송수신을 진행하는데, UDP는 이런 Connection 과정이 필요없고, UDP 클라이언트로부터 데이터를 직접 받아서 처리하면 된다.
따라서 UDP 서버는 UDP 클라이언트와 거의 동일한 기능을 갖기 때문에 별도의 UDP 서버 클래스가 없고, UdpClient클래스를 같이 사용하면 된다.

UDP 서버 예제

using System;
using System.Net;
using System.Net.Sockets;

namespace UdpSrv
{
    class Program
    {
        static void Main(string[] args)
        {
            // (1) UdpClient 객체 성성. 포트 7777 에서 Listening
            using (UdpClient srv = new UdpClient(7777))
            {
                // 클라이언트 IP를 담을 변수
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

                while (true)
                {
                    // (2) 데이타 수신
                    byte[] dgram = srv.Receive(ref remoteEP);
                    Console.WriteLine("[Receive] {0} 로부터 {1} 바이트 수신", remoteEP.ToString(), dgram.Length);

                    Thread.Sleep(500);

                    // (3) 데이타 송신
                    srv.Send(dgram, dgram.Length, remoteEP);
                    Console.WriteLine("[Send] {0} 로 {1} 바이트 송신", remoteEP.ToString(), dgram.Length);
                }
            }
        }
    }
}

위 예제를 각 스텝별로 살펴보면,

  1. UDP 클라이언트로부터 데이타를 받아들이기 위해 먼저 Listening할 포트를 지정하며 UdpClient 객체를 생성한다.
  2. UDP 에서 데이타를 수신하기 위해 UdpClient 객체의 Receive() 메서드를 사용한다. Receive() 메서드는 특히 수신 데이타와 함께 상대 UDP 클라이언트 종단점(IP주소와 포트) 정보도 같이 전달받는데, 이를 위해 IPEndPoint 객체를 ref 파라미터로 전달한다. 데이타 수신 후, ref 파라미터를 체크하면 데이타를 보낸 UDP 클라이언트의 IP 주소와 포트를 알 수 있다.
  3. UdpClient 객체의 Send() 메서드를 사용하여 데이타를 UDP 클라이언트로 전달한다. 이 때 클라이언트 IP는 위의 Receive() 메서드에서 받아온 IP 주소를 사용한다.
  4. 마지막으로 UdpClient 객체를 닫는다.

아래 그림은 위의 UDP 서버와 이전 아티클의 UDP 클라이언트 예제를 실행시킨 화면이다.

UdpClient 예제

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using static System.Console;
 
namespace UdpCli
{
    class Program
    {
        static void Main(string[] args)
        {
            // (1) UdpClient 객체 성성
            UdpClient cli = new UdpClient();
 
            string msg = "안녕하세요";
            byte[] datagram = Encoding.UTF8.GetBytes(msg);
             
            // (2) 데이타 송신
            cli.Send(datagram, datagram.Length, "127.0.0.1", 7777);
            WriteLine("[Send] 127.0.0.1:7777 로 {0} 바이트 전송", datagram.Length);
 
            // (3) 데이타 수신
            IPEndPoint epRemote = new IPEndPoint(IPAddress.Any, 0);
            byte[] bytes = cli.Receive(ref epRemote);
            WriteLine("[Receive] {0} 로부터 {1} 바이트 수신", epRemote.ToString(), bytes.Length);
 
            // (4) UdpClient 객체 닫기
            cli.Close();
        }
    }
}
  1. UDP 통신을 위해 System.Net.Sockets 네임스페이스의 UdpClient 객체를 생성한다. UdpClient 생성자에서 서버와 포트를 줄 수도 있지만, 만약 하나의 UdpClient 객체로 여러 서버에 데이타를 보낼 경우는 Send() 메서드에서 서버와 포트를 지정한다.
  2. UdpClient 객체의 Send() 메서드를 사용하여 데이타(UDP에서 datagram 이라 함)를 서버로 보낸다. 네트워크 데이타 송수신은 기본적으로 바이트 데이타를 사용하는데, 따라서 문자열을 보낼 경우 먼저 바이트로 인코딩한 후 보내게 된다. 보통 일반 영문은 ASCII로 인코딩하고, 한글 등 비영문 문자열은 UTF 인코딩을 사용한다.
    UDP 데이타그램은 최대 65,507 바이트까지 전송할 수 있다.
  3. UDP에서 데이타를 수신할 경우는 UdpClient 객체의 Receive() 메서드를 사용한다. Receive() 메서드는 특히 수신 데이타와 함께 상대 컴퓨터의 종단점(IP주소와 포트) 정보도 같이 전달받는데, 이를 위해 IPEndPoint 객체를 ref 파라미터로 전달한다. 이를 통해 데이타가 수신되면 누가 그 데이타를 전송했는지 알 수 있다. TCP와 달리 UDP는 Connectionless 프로토콜이기 때문에 이렇게 누가 보낸 데이타인지를 알 필요가 있다.
  4. 마지막으로 UdpClient 객체를 닫는다.
profile
기록해야 (살아)남는다 !

0개의 댓글