비연결형 소켓 OF (C++) 편


총 3개의 Layer로 구성됨

16 byte    : 머신, 혹은 App 을 구별할 GUID(UUID)
1  byte     : 0 ~ 255 까지의 message type 분류
data bytes : 실제 데이터  



* c# 용 비연결형 udp 소켓은 ( http://yamecoder.tistory.com/367 )


Communicaotr.h 싱글톤 Singleton<T> 는 ( http://yamecoder.tistory.com/368 )

#pragma once

/**
* [ Udp Communicator ]
*
* @author  yamecoder
* @version 17/02/24
*/


#include "Singleton.h"
#include "ofxNetwork.h"
#include "ofMain.h"

class Communicator : public Singleton<Communicator> , ofThread
{
public:
    const static char data_type_json = 0;
    const static char data_type_vec2 = 1;
    const static char data_type_text = 2;

private:
    bool is_setup = false;
    char* byte_id;
    ofxUDPManager udp_listener;
    ofxUDPManager udp_sender;
    
    char* buf_received_data;
    int buf_received_data_len = 10000;
    int byte_position = 0;

public:
    Communicator();
    ~Communicator();

    void Setup();

    void Send(char message_type, string str);

private:
    char* GenGuid();
    void threadedFunction();
    char* readData(int size);
};




ㅁㅁㅁ

Communicaotr.cpp

/**
* [ Udp Communicator ]
* 
* @author  yamecoder 
* @version 17/02/24
*/


#include "Communicator.h"
#include <objbase.h>

Communicator::Communicator()
{
    
}

Communicator::~Communicator()
{
}

void Communicator::Setup()
{
    if (is_setup == true)
        return;
    is_setup = true;

    byte_id = GenGuid();
    buf_received_data = new char[buf_received_data_len];

    //setup udp
    udp_listener.Create();
    udp_listener.BindMcast("224.0.0.0", 9999);
    
    udp_sender.Create();
    udp_sender.ConnectMcast("224.0.0.0", 9999);


    startThread();
}

void Communicator::Send(char message_type , string str)
{
    vector<char> data;
    for (size_t i = 0; i < 16; i++)
    {
        data.push_back(byte_id[i]);                 // insert byte_id(guid) of this machine
    }

    data.push_back(message_type);                   // insert message type (0 ~ 255 , 1byte)

    for (size_t i = 0; i < str.length(); i++)
    {
        data.push_back(str.c_str()[i]);             // insert message bytes
    }
    
    udp_sender.Send(&data[0], data.size());
}

char* Communicator::GenGuid()
{
    char* n_id = new char[16];

    GUID newId;
    HRESULT hr = CoCreateGuid(&newId);
    char* re_id = reinterpret_cast<char*>(&newId.Data4[0]);

    if (SUCCEEDED(hr))
    {
        char raw_id[16]
        {
            (newId.Data1 >> 24) & 0xFF,
            (newId.Data1 >> 16) & 0xFF,
            (newId.Data1 >> 8) & 0xFF,
            (newId.Data1) & 0xff,

            (newId.Data2 >> 8) & 0xFF,
            (newId.Data2) & 0xff,

            (newId.Data3 >> 8) & 0xFF,
            (newId.Data3) & 0xFF,

            (char)newId.Data4[0],
            (char)newId.Data4[1],
            (char)newId.Data4[2],
            (char)newId.Data4[3],
            (char)newId.Data4[4],
            (char)newId.Data4[5],
            (char)newId.Data4[6],
            (char)newId.Data4[7]
        };
        memcpy(n_id, raw_id, 16);

    }
    else
    {
        n_id = new char[16];
        for (size_t i = 0; i < 16; i++)
        {
            n_id[i] = char(i);
        }
    }
    

    return n_id;
}


void Communicator::threadedFunction()
{
    cout << "started !" << endl;
    while (isThreadRunning())
    {
        //wait
        udp_listener.Receive(buf_received_data, buf_received_data_len);
        
        //start read
        byte_position = 0;

        //read 16 bytes for sender guid.
        char* sender_id = readData(16);

        // check reflection
        bool check_myself = memcmp(sender_id, byte_id, 16);

        //release mem
        delete[] sender_id;
        
        if (check_myself != false)
        {
            char* type = readData(1);
            char* str = readData(buf_received_data_len - byte_position);




            // your code.
            if (type[0] == data_type_text)
            {

            }
            else if (type[0] == data_type_json)
            {

            }
            else if (type[0] == data_type_vec2)
            {

            }
            cout << str << endl;
            // end your code





            //release mem
            delete[] type;
            delete[] str;

            //clear buffer mem
            fill_n(buf_received_data, buf_received_data_len, 0);
        }
        else {
            // cout << "relfected form this machine" << endl;
        }
        


    }
}

char* Communicator::readData(int size)
{
    char* data = new char[size];
    memcpy(data, buf_received_data + byte_position, size);
    byte_position += size;
    return data;
}




저작자 표시
신고
Yamecoder 야매코더_
C++(oF) 2017.02.24 11:13
Powerd by Tistory, designed by criuce
rss