CoAP 알아보기 - slog(완료)

학교에서 학생에게 IoT 네트워크 프로그래밍을 가르치고 있는데, 다음 주 강의에서 CoAP를 가르쳐야 합니다.
IoT나 M2M 관련 현업에 있지 않고서는 CoAP를 접하기란 쉽지 않습니다. 저 또한 CoAP 관련 경험은 없습니다. 이론적으로 가르칠 수준의 학습은 금방 가능했는데, 또한 프로그래머이므로 CoAP를 직접 체험하고자 합니다.

먼저 정의부터 알아봅시다. 우리에게는 위키백과가 있습니다.

CoAP는 UPnP에서 사용되는 HTTPU(HTTP의 UDP 버젼)의 기능을 IoT나 M2M 환경에서 사용할 수 있도록 특화하여 만든 것을 알 수 있습니다. UDP/IP 기반이고요, 유니캐스트 및 멀티캐스트를 활용한다고 합니다. 쉽게 HTTP 로 변환할 수 있도록 설계되었다고 합니다.

1개의 좋아요

정성태님의 CoAP 관련 글입니다.

https://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&pageno=0&detail=1&wid=12629

성태님이 잘 말씀하신 대로, 어짜피 UDP/IP 기반의 프로토콜이므로 PC나 모바일 환경에서 사용하지 못하리란 법도 없습니다.

1개의 좋아요

언어 별 CoAP 라이브러리도 쉽게 접근할 수 있도록 위키백과에서 잘 소개하고 있습니다.

또,

https://coap.technology/

이곳을 통해 CoAP에 관련된 유용한 지료를 볼 수 있습니다.

1개의 좋아요

Python 및 C# CoAP 언어 구현체 입니다.

1개의 좋아요

또,

https://coap.technology/tools.html

이곳에서 CoAP관련 다양한 툴들을 확인할 수 있습니다.

1개의 좋아요

이제 CoAP .NET 라이브러리를 이용해서 C#에서 CoAP관련 코딩을 하도록 해보겠습니다.

교육 환경이 WSL2 + Visual Studio Code 이므로 먼저 WSL2 터미널로 Console 프로젝트를 생성합니다.

image

그리고 CoAP.NET 패키지를 등록합니다.

dotnet add package CoAP

image

그리고 Visual Studio Code를 실행 합니다.

code .

image

터미널에서 CoAP 패키지가 등록 후 잘 실행되는지를 확인합니다.

dotent run
/home/dimohy/study/l5/l5.csproj : warning NU1701: Package 'CoAP 1.1.0' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.
/home/dimohy/study/l5/l5.csproj : warning NU1701: Package 'CoAP 1.1.0' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.

image

흠, .NET Framework 용 패키지가 설치가 된 듯 하군요. CoAP.NET.Core를 설치해야만 했었습니다.

dotnet remove package CoAP

한 후,

dotnet add package CoAP.NET.Core

를 다시 해주고 dotnet run 해봅니다.

dimohy@dimohy-nb:~/study/l5$ dotnet run
Hello, World!

잘 등록됐군요! ^^;;;

1개의 좋아요

먼저 GitHub에 있는 소스코드를 따라 해봅시다. 접속을 해야 하므로 서버 먼저 만들어 봅니다.

using CoAP.Server;
using CoAP.Server.Resources;


var s = new CoapServer();
s.Add(new HelloWorldResource());
s.Start();

Console.WriteLine("Press any key to exit...");
Console.ReadLine();

class HelloWorldResource : Resource
{
    public HelloWorldResource() : base("hello-world")
    {
        Attributes.Title = "Get a friendly greeting!";
    }

    protected override void DoGet(CoapExchange exchange)
    {
        exchange.Respond("Hello World from CoAP.NET!");
    }
}
$ dotnet run
Press any key to exit...

오 잘 실행됩니다. CoAP.NET에서 제공하는 기능은 다양하겠지만, 일단 HelloWorldResource라는 자원을 생성했고, 자원을 “hello-world” 라는 이름으로 등록했습니다. 이제 클라이언트 코딩을 해서 통신 테스트를 해봅시다.

클라이언트를 별도의 프로젝트로 만드는 것은 좀 번거로우므로 명령줄 인자로 분기하도록 합시다.

using CoAP;
using CoAP.Server;
using CoAP.Server.Resources;


if (args.Length == 0 || args[0] != "S" && args[0] != "C")
{
    Console.WriteLine(@"No command line arguments.
S : Server
C : Client
");
    return;
}

var cmd = args[0];

if (cmd == "S")
{
    var s = new CoapServer();
    s.Add(new HelloWorldResource());
    s.Start();

    Console.WriteLine("Press any key to exit...");
    Console.ReadLine();
}
else if (cmd == "C")
{
    var req = new Request(Method.GET);
    req.URI = new("coap://[::1]/hello-world");
    req.Send();

    var res = req.WaitForResponse();
    Console.WriteLine($"Response : {res.ResponseText}");
}

class HelloWorldResource : Resource
{
    public HelloWorldResource() : base("hello-world")
    {
        Attributes.Title = "Get a friendly greeting!";
    }

    protected override void DoGet(CoapExchange exchange)
    {
        exchange.Respond("Hello World from CoAP.NET!");
    }
}

dotnet build를 한번 해주고, 서버는 dotnet run S로 먼저 띄운 후 dotnet run C로 클라이언트를 실행해봅니다.

$ dotnet run C
Response : Hello World from CoAP.NET!

잘 실행되는군요!

1개의 좋아요

CoAP는 CoAP Observe라고 해서 주거니 받거니 하지 않고 한번 구독 신청 후, 이후 주기적으로 정보를 수신하는 기능도 있습니다.

Observing Resources in CoAP (ietf.org)

Microsoft Word - CPL-TR-17-01-CoAP-Observe (knu.ac.kr)

1개의 좋아요

이제 Python으로도 해봅시다. Python에서는 CoAPthon으로 학습을 진행하려 합니다.

먼저, CoAPthon을 pip를 통해 설치합니다.

sudo pip3 install CoAPthon3

이후 code l5.py로 Visual Studio Code에서 파이선 코드를 연 후,

from coapthon.server.coap import CoAP

print('!')

를 통해 해당 패키지가 잘 포함 되는지 확인합니다. 문제 없이 포함 되었군요. 이후 깃허브에 나와있는 예제 참고 삼아 코딩합니다.

from coapthon.server.coap import CoAP
from coapthon.resources.resource import Resource

class HelloWorldResource(Resource):
    def __init__(self, name="hello-world", coap_server=None):
        super(HelloWorldResource, self).__init__(name, coap_server, visible=True, observable=True, allow_children=True)

        self.payload = "Get a friendly greeting!"
    
    def render_GET(self, request):
        self.payload = 'Hello World from CoAPthon!'
        return self

class CoAPServer(CoAP):
    def __init__(self, host, port):
        CoAP.__init__(self, (host, port))
        self.add_resource('hello-world/', HelloWorldResource())


def main():
    server = CoAPServer("0.0.0.0", 5683)
    try:
        server.listen(10)
    except KeyboardInterrupt:
        print("Server Shutdown")
        server.close()
        print("Exiting...")

if __name__ == '__main__':
    main()

이름을 l5-server.py라고 하고 실행합니다.

python3.9 l5-server.py

다음은 클라이언트 코드입니다. 이름을 l5-client.py로 합니다.

from coapthon.client.helperclient import HelperClient

host = "127.0.0.1"
port = 5683
path = "hello-world"

client = HelperClient(server=(host, port))
response = client.get(path)
print(response.payload)
client.stop()

python3.9 l5-client.py로 실행해 봅니다.

$ python3.9 l5-client.py
Hello World from CoAPthon!

잘됩니다. 이제 C#으로 만든 CoAP 서버를 띄워 동일하게 테스트 해봅니다.

$ python3.9 l5-client.py
Hello World from CoAP.NET!

프로그래밍 언어와 상관없이 상호 CoAP로 통신이 잘 되는 것을 확인할 수 있습니다!

2개의 좋아요