[C/C++ 네트워크 프로그래밍] POCO 라이브러리의 특징

POCO 라이브러리의 특징

http://coreafive.egloos.com/7371763

본 내용은 <POCO를 이용한 C++ 네트워크 프로그래밍>을 읽고 내 머리속에 정리된 내용을 남겨본다.
 
POCO라이브러리는 boost::asio처럼 네트워크 라이브러리이다.
기존의 socket 프로그래밍을 할려면 초기화-bind-listen이라는 과정을 알아야 하는 데 이런 라이브러리를 사용하면 안에서 그러한 내부적인 처리를 다 하기 때문에 사용하는 입장에서는 구현에만 집중하면 된다.
 
일단 POCO는 멀티플랫폼을 지향하여 JAVA의 클래스라이브러리, .NET프레임워크 인터페이스를 지향하기 때문에 비슷한 부분이 많으며 코딩스타일이나 이런 것 역시 잘 지키기 때문에 코드 가독성이 좋다.
또한 무엇보다 오픈소스이기 때문에 상용/비상용에서 무료로 모두 사용할 수 있다.
 
기능적으로는 IOCP와 같은 기능은 제공해주지 않으며 HTTP서버와 클라이언트, TCP 서버 프레임워크(멀티스레드), FTP 클라이언트, 메일 전송을 위한 SMTP 클라이언트, 수신용 POP3 클라이언트를 제공한다.
 
Boost::asio에 지원하지 않는 부가적인 기능을 많이 제공해주므로 asio를 사용하더라도 보조적인 도구로 POCO를 사용하여도 좋다는 조언이 있다.
 
TCP에코서버와 클라이언트 예제를 보면서 POCO의 소개를 마쳐본다.
 
TCP에코 서버
 
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
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"
 
const Poco::UInt16 PORT = 32452;
 
void main()
{
    std::cout << "서버 초기화 시작" << std::endl;
 
    Poco::Net::SocketAddress server_add(PORT);
    
    Poco::Net::ServerSocket server_sock(server_add);
 
    std::cout << "서버 초기화 완료. 클라이언트 접속 대기 중..." << std::endl;
 
    while (true)
    {
        // 클라이언트로부터 접속 요청을 수락한다.
        Poco::Net::StreamSocket ss = server_sock.acceptConnection();
 
        try
        {
            char buffer[256= { 0, };
            int n = ss.receiveBytes(buffer, sizeof(buffer));
            std::cout << "클라이언트에서 받은 메시지: " << buffer << std::endl;
 
            while (n > 0)
            {
                char szSendMessage[256= { 0, };
                sprintf_s(szSendMessage, 256 - 1"Re:%s", buffer);
                int nMsgLen = strnlen_s(szSendMessage, 256 - 1);                
 
                ss.sendBytes(szSendMessage, sizeof(buffer));
 
                n = ss.receiveBytes(buffer, sizeof(buffer));
                std::cout << "클라이언트에서 받은 메시지: " << buffer << std::endl;
            }
 
            std::cout << "클라이언트와 연결이 끊어졌습니다." << std::endl;
        }
        catch (Poco::Exception& exc)
        {
            std::cout << "EchoServer: " << exc.displayText() << std::endl;
        }
    }
 
    getchar();
}
cs
 
TCP에코 클라이언트
 
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
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/SocketAddress.h"
 
const Poco::UInt16 PORT = 32452;
 
void main()
{
    std::cout << "서버에 연결 시도..." << std::endl;
    Poco::Net::StreamSocket ss;
 
    try
    {
        ss.connect(Poco::Net::SocketAddress("localhost", PORT));
 
        for (int i = 0; i < 7++i)
        {
            char szMessage[128= { 0, };
 
            sprintf_s(szMessage, 128 - 1"%d - Send Message", i);
 
            int nMsgLen = strnlen_s(szMessage, 128 - 1);
            ss.sendBytes(szMessage, nMsgLen);
 
            std::cout << "서버에 보낸 메시지: " << szMessage << std::endl;
 
            char buffer[256= { 0, };
            auto len = ss.receiveBytes(buffer, sizeof(buffer));
 
            if (len <= 0)
            {
                std::cout << "서버와 연결이 끊어졌습니다" << std::endl;
                break;
            }
 
            std::cout << "서버로부터 받은 메시지: " << buffer << std::endl;
        }
 
        ss.close();
    }
 
    catch (Poco::Exception& exc)
    {
        std::cout << "서버 접속 실패" << exc.displayText() << std::endl;
    }
 
    getchar();
}
cs
 
우리가 처음 배울 때 이런 프로그램을 만드는 데 그런 코드와 비교했을 때 상당히 짧고 가독성이 높아보이는게 POCO라이브러리의 장점이 아닐까한다.
 
이어서 UDP도 비교를 위해서 올려본다.
 
UDP 에코 클라이언트
 
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
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/DatagramSocket.h"
 
const Poco::UInt16 MY_PORT = 32451;
const Poco::UInt16 OTHER_PORT = 32452;
 
void main()
{
    // UDP는 클라이언트와 서버가 연결된 상태가 아니므로 소켓 생성시 사용할 포트 번호를 설정해줘야 한다.
    Poco::Net::DatagramSocket ss(MY_PORT);
 
    try
    {
        for (int i = 0; i < 7++i)
        {
            char szMessage[128= { 0, };
 
            sprintf_s(szMessage, 128 - 1"%d - Send Message", i);
 
            int nMsgLen = strnlen_s(szMessage, 128 - 1);
 
            // 서버에 데이터를 보낼 함수를 호출할 때마다 데이터 받을 곳의 주소를 지정한다.
            // Poco::Net::SocketAddress("localhost", OTHER_PORT)
            ss.sendTo(szMessage, nMsgLen, Poco::Net::SocketAddress("localhost", OTHER_PORT));
 
            std::cout << "서버에 보낸 메시지: " << szMessage << std::endl;
 
            char buffer[256= { 0, };
 
            // 서버와 연결된 상태가 아니므로 해당 받은 데이터가 어디로부터 왔는지를 알기 위해 세번째 인자인
            // sender를 넘겨준다.
            // 그러면 이 sender에 설정된 정보를 통해서 어디서 왔는지를 알 수 있다.
            Poco::Net::SocketAddress sender;
            auto len = ss.receiveFrom(buffer, sizeof(buffer), sender);
 
            if (len <= 0)
            {
                std::cout << "서버와 연결이 끊어졌습니다" << std::endl;
                break;
            }
 
            std::cout << "서버로부터 받은 메시지: " << buffer << std::endl;
        }
 
        ss.close();
    }
 
    catch (Poco::Exception& exc)
    {
        std::cout << "서버 접속 실패" << exc.displayText() << std::endl;
    }
 
    getchar();
}
cs
 
 
UDP 에코 서버i
 
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
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketAddress.h"
 
const Poco::UInt16 MY_PORT = 32452;
 
void main()
{
    Poco::Net::DatagramSocket serv_sock(MY_PORT);
    Poco::Net::SocketAddress client;    
 
    while (true)
    {
        try
        {
            char buffer[256= { 0, };
 
            Poco::Net::SocketAddress sender;
            int len = serv_sock.receiveFrom(buffer, sizeof(buffer), sender);
 
            if (len > 0)
            {
                std::cout << buffer << " from " << sender.host().toString() << ":" << sender.port() << std::endl;
 
                char szSendMessage[256= { 0, };
                sprintf_s(szSendMessage, 256 - 1"Re:%s", buffer);
                int nMsgLen = strnlen_s(szSendMessage, 256 - 1);                
 
                serv_sock.sendTo(szSendMessage, sizeof(buffer), sender);
            }
        }
        catch (Poco::Exception& exc)
        {
            std::cout << "EchoServer: " << exc.displayText() << std::endl;
        }
    }
 
    getchar();
}
cs
 

[출처] http://egloos.zum.com/coreafive/v/7371763

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수

등록된 글이 없습니다.

대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED