Posts UDP 소켓 서버, 클라이언트 기본
Post
Cancel

UDP 소켓 서버, 클라이언트 기본

UDP 소켓 통신의 특징


  • 서버와 클라이언트 간의 1:1 연결이 생성되지 않는다.
  • 리스너 소켓이 필요하지 않다.
  • Listen(), Connect() 과정이 없다.
  • 소켓의 .ReceiveFrom(), .SendTo() 메소드를 통해 엔드포인트와 데이터를 주고 받는다.


소켓 통신 과정


서버

  • 서버 IP 주소, 포트를 통해 서버 엔드포인트 생성
  • 서버 소켓 객체 생성
  • Bind(서버 엔드포인트 정보를 서버 소켓에 연동)
  • 클라이언트에 대응할 리모트 엔드포인트 생성
  • Send => 리모트 엔드포인트
  • Receive <= 리모트 엔드포인트
  • Close

클라이언트

  • 서버 IP 주소, 포트를 통해 서버 엔드포인트 생성
  • 클라이언트 소켓 객체 생성
  • 리모트 엔드포인트 생성
  • Send => 서버 엔드포인트
  • Receive <= 리모트 엔드포인트
  • Close


서버 소켓 기본


[1] 서버 데이터 정의

1
2
3
4
5
6
// 서버 IP 주소 정의
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); // 로컬 호스트
IPAddress ipAddr = ipHost.AddressList[0];

// 서버 엔드 포인트 생성
IPEndPoint ep = new IPEndPoint(ipAddr, 1234);

[2] 서버 소켓 생성

1
2
3
4
5
// 서버 소켓 생성
Socket serverSocket = new Socket(ep.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            
// 서버 소켓에 엔드 포인트 바인딩
serverSocket.Bind(ep);

[3] 리모트 엔드 포인트 생성

1
2
3
// 주소와 포트는 상관 없고, AddressFamily만 소켓과 맞추면 됨
// 어차피 Receive로부터 초기화됨
EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0000);


[4] 데이터 송수신

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Send    => Remote End Point
// Receive <= Remote End Point

int index = 0;
while (true)
{
    // Receive
    byte[] recvBuffer = new byte[1024];
    int recvLen = serverSocket.ReceiveFrom(recvBuffer, ref remoteEP);
    string recvString = Encoding.UTF8.GetString(recvBuffer, 0, recvLen);

    Console.WriteLine($"Received From Client [{remoteEP}] : {recvString}");

    // Send
    string replyToClient = $"Server Replied - {index++}";
    serverSocket.SendTo(Encoding.UTF8.GetBytes(replyToClient), remoteEP);

    Console.WriteLine($"Send Data : {replyToClient}\n");
}

serverSocket.Close();
Console.WriteLine("Server Stopped");


클라이언트 소켓 기본


[1] 연결할 서버 데이터 정의

1
2
3
4
5
6
// 서버 IP 주소 정의
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); // 로컬 호스트
IPAddress ipAddr = ipHost.AddressList[0];

// 서버 엔드 포인트 생성
IPEndPoint ep = new IPEndPoint(ipAddr, 1234);

[2] 클라이언트 소켓 생성

1
2
// 클라이언트 소켓 생성
Socket clientSocket = new Socket(serverEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

[3] 리모트 엔드 포인트 생성

1
2
3
// 주소와 포트는 상관 없고, AddressFamily만 소켓과 맞추면 됨
// 어차피 Receive로부터 초기화됨
EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0000);

[4] 데이터 송수신

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Send    => Server End Point
// Receive <= Remote End Point

while (true)
{
    Console.Write("Send To Server : ");
    string consoleInputString = Console.ReadLine();
    if (consoleInputString == "exit")
        break;

    // Send
    byte[] sendBuffer = Encoding.UTF8.GetBytes(consoleInputString);
    clientSocket.SendTo(sendBuffer, sendBuffer.Length, SocketFlags.None, serverEP);

    // Receive
    byte[] recvBuffer = new byte[1024];
    int recvLen = clientSocket.ReceiveFrom(recvBuffer, ref remoteEP);
    string recvString = Encoding.UTF8.GetString(recvBuffer, 0, recvLen);
    Console.WriteLine($"Received From Server [{remoteEP}] : {recvString}\n");
}

clientSocket.Close();
Console.WriteLine("Client Stopped");


전체 소스 코드


UdpServerBasic.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

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

class UdpServerBasic
{
    public static void Run()
    {
        Console.WriteLine("UDP SERVER RUNNING..");

        // ============== [1] 내(서버) 데이터 정의 ========================

        // 서버 IP 주소 정의
        IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); // 로컬 호스트
        IPAddress ipAddr = ipHost.AddressList[0];

        // 서버 엔드 포인트 생성
        IPEndPoint ep = new IPEndPoint(ipAddr, 1234);

        // 서버 소켓 생성
        Socket serverSocket = new Socket(ep.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            
        // 서버 소켓에 엔드 포인트 바인딩
        serverSocket.Bind(ep);

        // ============== [2] 리모트 엔드 포인트 정의 =====================

        // 주소와 포트는 상관 없고, AddressFamily만 소켓과 맞추면 됨
        // 어차피 Receive로부터 초기화됨
        EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0000);

        // ============== [3] 통 신 =======================================

        // Send    => Remote End Point
        // Receive <= Remote End Point

        int index = 0;
        while (true)
        {
            // Receive
            byte[] recvBuffer = new byte[1024];
            int recvLen = serverSocket.ReceiveFrom(recvBuffer, ref remoteEP);
            string recvString = Encoding.UTF8.GetString(recvBuffer, 0, recvLen);

            Console.WriteLine($"Received From Client [{remoteEP}] : {recvString}");

            // Send
            string replyToClient = $"Server Replied - {index++}";
            serverSocket.SendTo(Encoding.UTF8.GetBytes(replyToClient), remoteEP);

            Console.WriteLine($"Send Data : {replyToClient}\n");
        }

        serverSocket.Close();
        Console.WriteLine("Server Stopped");
    }
}
UdpClientBasic.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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

class UdpClientBasic
{
    public static void Run()
    {
        Console.WriteLine("UDP Client Running....\n");

        // ============== [1] 연결할 서버 데이터 정의 =================

        // 서버 IP 주소 정의
        IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName()); // 로컬 호스트
        IPAddress ipAddr = ipHost.AddressList[0];

        // 서버 엔드 포인트 생성
        IPEndPoint serverEP = new IPEndPoint(ipAddr, 1234);

        // ============== [2] 클라이언트 데이터 정의 =================

        // 클라이언트 소켓 생성
        Socket clientSocket = new Socket(serverEP.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

        // 주소와 포트는 상관 없고, AddressFamily만 소켓과 맞추면 됨
        // 어차피 Receive로부터 초기화됨
        EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0000);

        // ============== [3] 통 신 =======================================

        // Send    => Server End Point
        // Receive <= Remote End Point

        while (true)
        {
            Console.Write("Send To Server : ");
            string consoleInputString = Console.ReadLine();
            if (consoleInputString == "exit")
                break;

            // Send
            byte[] sendBuffer = Encoding.UTF8.GetBytes(consoleInputString);
            clientSocket.SendTo(sendBuffer, sendBuffer.Length, SocketFlags.None, serverEP);

            // Receive
            byte[] recvBuffer = new byte[1024];
            int recvLen = clientSocket.ReceiveFrom(recvBuffer, ref remoteEP);
            string recvString = Encoding.UTF8.GetString(recvBuffer, 0, recvLen);
            Console.WriteLine($"Received From Server [{remoteEP}] : {recvString}\n");
        }

        clientSocket.Close();
        Console.WriteLine("Client Stopped");
    }
}


References


This post is licensed under CC BY 4.0 by the author.