cJSON Programming

Programming 2015.11.29 20:56


Project에서 json을 사용하기로 하였습니다.

그리하여 어떤 json parser를 사용할까 하다가 아래의 cjson parser 를 사용하기로 하였습니다.


http://sourceforge.net/projects/cjson/


이유는 가장 간단하고 사용하기 편리한 듯 하였기 때문입니다.

개인적으로 simple is the best 라는 믿음이 아주 강하기 때문입니다.


아시다시피 json은 간단히 key = value 라는 구조를 가지고 있습니다.


cJSON.h 파일을 열어보시면 다음과 같이 매크로들을 확인할 수가 있습니다.

아마 아래 미리 정의된 매크로들을 주로 사용할 것입니다.

 

/* Macros for creating things quickly. */

#define cJSON_AddNullToObject(object,name)              cJSON_AddItemToObject(object, name, cJSON_CreateNull())

#define cJSON_AddTrueToObject(object,name)              cJSON_AddItemToObject(object, name, cJSON_CreateTrue())

#define cJSON_AddFalseToObject(object,name)             cJSON_AddItemToObject(object, name, cJSON_CreateFalse())

#define cJSON_AddBoolToObject(object,name,b)    cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))

#define cJSON_AddNumberToObject(object,name,n)  cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))

#define cJSON_AddStringToObject(object,name,s)  cJSON_AddItemToObject(object, name, cJSON_CreateString(s))



json도 엄연히 데이터 이므로 전체적인 데이터 구조를 미리 생각해야 합니다.

뭔말이즉슨 xml를 사용할때 스키마 구조를 먼저 잡듯이 비슷하다고 보시면 됩니다.


샘플을 보시면 바로 이해가 될것입니다.

좀더 자세히 설명하기에는 그다지 설명할 것이 너무 없어서...

다시 업데이트 하도록 하겠습니다.

저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

cJSON Programming  (0) 2015.11.29
scons 개념 및 사용법  (0) 2015.04.08
DHCP Probe 소스 코드  (0) 2014.11.29
현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
Posted by sound79 사운드친구

댓글을 달아 주세요


AllSeen Alliance의 AllJoyn을 컴파일 하기 위해서 scons을 사용해야 된다는 것을 알게 되었고,

그 필요에 의하여 scons에 관련해서 잠깐 조사 및 공부한 내용을 정리할 목적입니다.


scons 공식 홈페이지: http://www.scons.org/

scons 기본 사용법: http://egloos.zum.com/bruceKIM/v/3399880

SConstructor 사용법: http://pkgpl.org/2014/07/27/sconstruct_basic/

scons wiki: http://en.wikipedia.org/wiki/SCons, http://ko.wikipedia.org/wiki/SCons


가장 기본적으로 생각할 것은 scons 는 Python 기반의 빌드툴입니다.

등장한지는 꽤 되었지만 그리 많이 사용되지는 않은 듯 합니다.


아무래도 리눅스의 약간 Geek적인 느낌이 Autoconf를 그대로 사용해 오게 하지 않았을까 하는 것이 개인적인

생각이며, 좀더 편리하게 사용하는 사용자라면 여러 IDE 툴이 지원하는 Build 시스템을 이용했을 거라는

생각이 드네요...


scons Frequently Asked Questions: http://www.scons.org/wiki/FrequentlyAskedQuestions


만약에 다음 프로젝트를 어떻게 할거냐고 하면,,, 아직은 그대로 Makefile을 사용할거라고 말할 것이다.

이유는 음....


저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

cJSON Programming  (0) 2015.11.29
scons 개념 및 사용법  (0) 2015.04.08
DHCP Probe 소스 코드  (0) 2014.11.29
현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
Posted by sound79 사운드친구

댓글을 달아 주세요

이전에 작성했던 현재 네트워크에서 DHCP 서버를 확인하는 글을 참고하여

http://sound79.tistory.com/169


간단하게 DHCP Probe 코드를  작성해 보았습니다.

소스코드를 보면 간단합니다. DHCP 패킷을 하나 만들어서 전송한 후 DHCP Offer 메시지를 일정 시간 기다립니다.

DHCP Offer 메시지를 수신하면 현재 네트워크에 DHCP Server가 존재한다고 판단하도록 되어 있습니다.


DHCPProbe.h

/*
 * DhcpProbe.h
 *
 *  Created on: 2014. 8. 17.
 *      Author: sound79@gmail.com
 */
#ifndef DHCPPROBE_H_
#define DHCPPROBE_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>
#include <string>

#define MAX_DHCP_CHADDR_LEN        16
#define MAX_DHCP_SNAME_LEN        64
#define MAX_DHCP_FILE_LEN        128
#define MAX_DHCP_OPTIONS_LEN    312

#define SERVER_DHCP_PORT        67
#define CLIENT_DHCP_PORT        68

#define CHECK_WAITTING_DHCP_OFFER_TIME        2

typedef struct DHCPPacket_t
{
    unsigned char  op;
    unsigned char  htype;
    unsigned char  hlen;
    unsigned char  hops;
#if 0
    unsigned long xid;
    unsigned short secs;
    unsigned short flags;
#else
    u_int32_t xid;
    u_int16_t secs;
    u_int16_t flags;
#endif
    struct in_addr ciaddr;
    struct in_addr yiaddr;
    struct in_addr siaddr;
    struct in_addr giaddr;
    unsigned char chaddr [MAX_DHCP_CHADDR_LEN];
    char sname [MAX_DHCP_SNAME_LEN];
    char file [MAX_DHCP_FILE_LEN];
    char options[MAX_DHCP_OPTIONS_LEN];

    void clear()
    {
        op = 0, htype = 0, hlen = 0 , hops = 0;
        xid = 0, secs = 0, flags = 0;
        memset(&ciaddr, 0, sizeof(ciaddr));
        memset(&yiaddr, 0, sizeof(ciaddr));
        memset(&siaddr, 0, sizeof(ciaddr));
        memset(&giaddr, 0, sizeof(ciaddr));
        memset(chaddr, 0, MAX_DHCP_CHADDR_LEN);
        memset(sname, 0, MAX_DHCP_SNAME_LEN);
        memset(file, 0, MAX_DHCP_FILE_LEN);
        memset(options, 0, MAX_DHCP_OPTIONS_LEN);
    }
}DHCPPacket;

using namespace std;

class DHCPProbe
{
private:
    DHCPPacket mDHCPPacket;
    string mEthName;
    string mEthMacAddress;
    int    mDHCPSocket;
    unsigned long mPacketXID;

private:
    bool makeDHCPSocket();
    void closeDHCPSocket();
    bool getMacAddress();
    bool makeDHCPDiscoveryPacket();
    bool sendDHCPDiscovery();
    int recvDHCPOffer(char *buffer, int buffer_size, struct sockaddr_in *sourceAddress);
    int waitDHCPOfferPacket();

public:
    DHCPProbe(string ethName = "eth0");
    virtual ~DHCPProbe();
    int CheckDHCPServerExist();
};

#endif /* DHCPPROBE_H_ */



DhcpProbe.cpp

DhcpProbe.cpp


DhcpProbe.h


/*
 * DhcpProbe.cpp
 *
 *  Created on: 2014. 8. 17.
 *      Author: sound79@gmail.com
 */

#include "DhcpProbe.h"

DHCPProbe::DHCPProbe(string ethName) : mDHCPPacket(), mEthName(ethName), mDHCPSocket(0), mPacketXID(0)
{
    //초기화 mDHCPPacket
}

DHCPProbe::~DHCPProbe()
{
}

bool DHCPProbe::makeDHCPSocket()
{
    struct sockaddr_in dhcpAddress;
    struct ifreq interface;

    memset(&dhcpAddress, 0, sizeof(dhcpAddress));
    dhcpAddress.sin_family=AF_INET;
    dhcpAddress.sin_port=htons(CLIENT_DHCP_PORT);
    dhcpAddress.sin_addr.s_addr=INADDR_ANY;
    memset(&dhcpAddress.sin_zero, 0, sizeof(dhcpAddress.sin_zero));

    int sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if(sock<0)
    {
        fprintf(stderr, "%s %s %d: create socket error!\n", __FILE__, __FUNCTION__, __LINE__);
        return false;
    }

    int flags = 1;
    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flags, sizeof(flags)) < 0)
    {
        fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
        return false;
    }

    if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&flags, sizeof flags) < 0)
    {
        fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
        return false;
    }

    memset(&interface.ifr_ifrn.ifrn_name, 0, IFNAMSIZ);
    if(mEthName.length() > IFNAMSIZ)
        strncpy(interface.ifr_ifrn.ifrn_name, mEthName.c_str(), IFNAMSIZ);
    else
        strncpy(interface.ifr_ifrn.ifrn_name, mEthName.c_str(), mEthName.length());

    if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0)
    {
        fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
        return false;
    }


    if(bind(sock, (struct sockaddr *)&dhcpAddress, sizeof(dhcpAddress)) < 0)
    {
        fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno));
        return false;
    }

    mDHCPSocket = sock;

    getMacAddress();

    return true;
}

void DHCPProbe::closeDHCPSocket()
{
    if(mDHCPSocket > 0)
        close(mDHCPSocket);
    mDHCPSocket = 0;
}

bool DHCPProbe::getMacAddress()
{
    struct ifreq ifr;
    strncpy((char *)&ifr.ifr_name, mEthName.c_str(), sizeof(ifr.ifr_name));

    if(ioctl(mDHCPSocket,SIOCGIFHWADDR,&ifr)<0)
    {
        fprintf(stderr, "%s %s %d: couldn't get mac address!\n", __FILE__, __FUNCTION__, __LINE__);
        return false;
    }
    char mac_address[7] = {0,};
    memcpy(&mac_address, &ifr.ifr_hwaddr.sa_data, 6);
    mEthMacAddress = mac_address;

    return true;
}

bool DHCPProbe::makeDHCPDiscoveryPacket()
{
    mDHCPPacket.clear();

    mDHCPPacket.op = 0x01;        //boot request
    mDHCPPacket.htype = 0x01;    //ethernet hardware address
    mDHCPPacket.hlen = 6;
    mDHCPPacket.hops = 0;
    srand(time(NULL));
    mPacketXID = random();
    mDHCPPacket.xid = htonl(mPacketXID);
    mDHCPPacket.secs = 0xFF;
    mDHCPPacket.flags = htons(32768);    //DHCP Broadcast flag
    if(mEthMacAddress.length() > 6)
        memcpy(mDHCPPacket.chaddr, mEthMacAddress.c_str(), mEthMacAddress.length());
    else
        memcpy(mDHCPPacket.chaddr, mEthMacAddress.c_str(), 6);

    mDHCPPacket.options[0] = '\x63';
    mDHCPPacket.options[1] = '\x82';
    mDHCPPacket.options[2] = '\x53';
    mDHCPPacket.options[3] = '\x63';
    mDHCPPacket.options[4] = 53;
    mDHCPPacket.options[5] = '\x01';
    mDHCPPacket.options[6] = 1;

    return true;
}

bool DHCPProbe::sendDHCPDiscovery()
{
    makeDHCPDiscoveryPacket();

    struct sockaddr_in destAddress;

    destAddress.sin_family = AF_INET;
    destAddress.sin_port = htons(67);
    destAddress.sin_addr.s_addr = INADDR_BROADCAST;
    memset(&destAddress.sin_zero, 0, sizeof(destAddress.sin_zero));

    int result = sendto(mDHCPSocket, reinterpret_cast<char *>(&mDHCPPacket), sizeof(mDHCPPacket), 0, reinterpret_cast<struct sockaddr *>(&destAddress), sizeof(destAddress));
    if(result < 0)
        return false;
    else
        return true;
}

int DHCPProbe::recvDHCPOffer(char *buffer, int buffer_size, struct sockaddr_in *sourceAddress)
{
    struct timeval tv;
    fd_set readfds;

    tv.tv_sec = CHECK_WAITTING_DHCP_OFFER_TIME;
    tv.tv_usec = 0;
    FD_ZERO(&readfds);
    FD_SET(mDHCPSocket, &readfds);
    select(mDHCPSocket+1, &readfds, NULL, NULL, &tv);

    if(FD_ISSET(mDHCPSocket, &readfds))
    {
        struct sockaddr_in src_addr;
        memset(&src_addr, 0, sizeof(src_addr));
        socklen_t address_size = sizeof(src_addr);
        recvfrom(mDHCPSocket,(char *)buffer, buffer_size, MSG_PEEK, (struct sockaddr *)&src_addr, &address_size);
        recvfrom(mDHCPSocket,(char *)buffer, buffer_size, 0, (struct sockaddr *)&src_addr, &address_size);
        fprintf(stderr, "%s %s %d:\n", __FILE__, __FUNCTION__, __LINE__);
        memcpy(sourceAddress, &src_addr, sizeof(src_addr));
    }
    else
    {
        fprintf(stderr, "%s %s %d:\n", __FILE__, __FUNCTION__, __LINE__);
        return 0;
    }

    return 1;
}

int DHCPProbe::waitDHCPOfferPacket()
{
    struct sockaddr_in source;
    time_t start_time;
    time_t check_time;
    time(&start_time);

    DHCPPacket buffer;

    while(1)
    {
        time(&check_time);
        if((check_time - start_time) >= CHECK_WAITTING_DHCP_OFFER_TIME)
            break;
        memset(&source, 0, sizeof(source));
        if(recvDHCPOffer(reinterpret_cast<char *>(&buffer), sizeof(buffer), &source) > 0)
        {
            fprintf(stderr, "%s\n", inet_ntoa(source.sin_addr));
        }
    }

    return 1;
}

int DHCPProbe::CheckDHCPServerExist()
{
    if(makeDHCPSocket() == false)
        return 0;

    if(sendDHCPDiscovery() == false)
        return 0;

    waitDHCPOfferPacket();
    closeDHCPSocket();

    return 1;
}

int main()
{
    DHCPProbe dhcp("eth0");
    dhcp.CheckDHCPServerExist();

    return 0;
}


저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

cJSON Programming  (0) 2015.11.29
scons 개념 및 사용법  (0) 2015.04.08
DHCP Probe 소스 코드  (0) 2014.11.29
현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
Posted by sound79 사운드친구

댓글을 달아 주세요


현재 연결된 네트워크에서 DHCP 서버가 동작 되고 있는지? 즉 이미 DHCP 서버가 동작 되고 있는 네트워크 인지를

판단해야 할 필요성이 생겼다.


먼저 DHCP 프로토콜에 대해서 간단히 살펴 보면 다음과 같습니다.


DHCP: http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol



(figure1 refer wikipedia)


위의 그림과 같이

(1). Client -> Server 로 DISCOVERY를 Broadcast

   : DHCP 서버가 있는지 패킷을 브로드 캐스팅한다.

(2). Server -> Client에서 OFFER로 Unicast

   : DHCP 서버는 DISCOVERY 메시지를 받으면 해당 Client에게 이 IP 사용할래? 라고 응답한다. 클라이언트의 MAC으로 전송한다.

(3). Client -> Server로 REQUEST를 Broadcast

   : Client는 OK.. 내 그 IP를 사용하겠다라고 응답한다.

(4). Server -> Client에서 ACK로 Unicast

   : Server는 그래 그 아이피 이제 너가 사용하는지 알겠어..


대충 이런식입니다.

제가 하고 싶고, 구현하고자 하는 것은 현재 연결된 망에 DHCP 서버가 있는지만 확인하면 되기 때문에... 위의 과정중에서

DISCOVERY를 하고 OFFER가 오면 현재 연결된 망에 DHCP 서버가 있다고 판단하면 될 듯 하다..



pseudo code

init program

   make discovery packet

   send(broadcast) discovery packet

   wait for offer packet from dhcp server

   close

end


대충 위와 같은 식으로 구현하면 될 듯 합니다.



이제 패킷의 구조를 확인해야 겠습니다.

http://www.tcpipguide.com/free/t_DHCPMessageFormat.htm



이제 상기 내용을 기반으로 DHCP 서버 Probe 를 구현하도록 하겠습니다. ^^

잠시 열심히 구현한 결과... 어느정도 동작하는 듯 합니다.

음... 오늘도 만족합니다. ^^




저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

scons 개념 및 사용법  (0) 2015.04.08
DHCP Probe 소스 코드  (0) 2014.11.29
현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
Posted by sound79 사운드친구

댓글을 달아 주세요

gsoap (2)

Programming 2014.03.12 12:00


참고로 제가 여기 적는 gsoap의 글들은 대부분 

http://www.cs.fsu.edu/~engelen/soap.html 의 Document의 User Guide를 참고하고 있습니다.

어떻게 보면 간단히 예제들을 한번 돌려보고 이해한 만큼 적는 것입니다.


오늘은 간단히 gsoap를 이용하여 웹서버의 CGI 를 구현해 보고자 합니다. 물론 gsoap의 기본 예제 그대로... ^^


1. 먼저 다음과 같은 헤더 파일을 만듭니다.

// File: currentTime.h 
//gsoap ns service name: currentTime 
//gsoap ns service namespace: urn:currentTime 
//gsoap ns service location: http://www.yourdomain.com/currentTime.cgi 
int ns__currentTime(time_t& response);


==> 이걸 currentTime.h로 저장한 soapcpp2 -S currentTime.h

       그럼 다음과 같은 파일들이 생성됩니다.

test$ ls

currentTime.currentTime.req.xml  currentTime.h      currentTime.wsdl  soapC.cpp  soapServer.cpp     soapStub.h

currentTime.currentTime.res.xml  currentTime.nsmap  ns.xsd            soapH.h    soapServerLib.cpp  soapcurrentTimeObject.h


아시다시피  soapcpp2 -S  <== '-S' 의 옵션은 Server-Side Code를 생성해 줍니다. 일단은 대충 그정도만 이해하고... 넘어가죠... 

여기서 잠깐 soapcpp2의 
=============================================================================
test$ soapcpp2 -h
Usage: soapcpp2 [-1|-2] [-C|-S] [-T] [-L] [-a] [-b] [-c] [-d path] [-e] [-f N] [-h] [-i] [-I path:path:...] [-k] [-l] [-m] [-n] [-p name] [-s] [-t] [-u] [-v] [-w] [-x] [-y] [infile]

-1      generate SOAP 1.1 bindings
-2      generate SOAP 1.2 bindings
-C generate client-side code only
-S generate server-side code only
-T generate server auto-test code
-L don't generate soapClientLib/soapServerLib
-a use SOAPAction HTTP/WSA header to invoke server-side operations
-b serialize byte arrays char[N] as string
-c      generate C source code
-dpath  use path to save files
-e generate SOAP RPC encoding style bindings
-fN file split of N XML serializer implementations per file (N>=10)
-h display help info
-Ipath  use path(s) for #import
-i      generate C++ service proxies and objects inherited from soap struct
-j      generate C++ service proxies and objects that share a soap struct
-k      generate data structure walkers (experimental)
-l      generate linkable modules (experimental)
-m      generate Matlab(tm) code for MEX compiler
-n      use service name to rename service functions and namespace table
-pname  save files with new prefix name instead of 'soap'
-qname  use name as the C++ namespace of all declarations
-s      generate deserialization code with strict XML validation checks
-t      generate code for fully xsi:type typed SOAP/XML messaging
-u uncomment comments in WSDL/schema output by suppressing XML comments
-v display version info
-w don't generate WSDL and schema files
-x don't generate sample XML message files
-y include C/C++ type access information in sample XML messages
infile header file to parse (or stdin)
=============================================================================

2. 그 다음 실제 cgi를 위한 구현부를 만듭니다.

// File: currentTime.cpp 
#include "soapH.h" // include the generated declarations 
#include "currentTime.nsmap" // include the XML namespace mappings 
int main() 

   // create soap context and serve one CGI-based request: 
   return soap_serve(soap_new()); 

int ns__currentTime(struct soap *soap, time_t& response) 

   response = time(0); 
   return SOAP_OK; 
}

==> 이걸 currentTime.cpp 로 저장한 다음, 아래와 같이 컴파일 합니다.

       g++ -o currentTime.cgi currentTime.cpp soapC.cpp soapServer.cpp -lgsoap++ 


3. 생성된 currentTime.cgi를 테스트 해봅니다.

currentTime$ ./currentTime.cgi < currentTime.currentTime.req.xml 

Status: 200 OK

Server: gSOAP/2.8

Content-Type: text/xml; charset=utf-8

Content-Length: 445

Connection: close


<?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:currentTime"><SOAP-ENV:Body><ns:currentTimeResponse><response>2014-03-10T13:12:18Z</response></ns:currentTimeResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>


4. currentTime.cgi를 웹서버의 /cgi-bin/ 에 copy 후 실행 권한을 줍니다.
==> /usr/lib/cgi-bin


5. 웹브라우저에서 실행해 보기

==> 대충 아래와 같은 형태로 나타나는데, 왠지 에러 같네요.. 아마도 XML 형태의 Request가 없어서 그런거지.. 계속 하다보면 답이 나오겠죠... ㅎㅎ 


저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

DHCP Probe 소스 코드  (0) 2014.11.29
현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
[C Programming] Struct Hack  (0) 2013.08.15
Posted by sound79 사운드친구

댓글을 달아 주세요

gsoap (1)

Programming 2014.03.11 12:00

gsoap 에 대해서 기본적인 것 부터 시작해보자


http://www.cs.fsu.edu/~engelen/soap.html



본 글에서부터는 오로지  C++에 대해서만 언급한다. 물론 gsoap 은 C 로도 프로그래밍이 가능하지만, C++로 하는것이 왠지..

그리고 soap에 대해서는 다루지 않는다.


gsoap을 하기위해서는 기본적으로  wsdl2h와 soapcpp2를 이용하여 wsdl, schema로부터 데이터를 바인딩하고(헤더파일 생성) soapcpp2로 stub, skeleton 코드(서버, 클라이언트 베이스) 를 생성한다는 것... ^^

  • The wsdl2h WSDL/schema importer and data binding mapper tool.
  • The soapcpp2 stub/skeleton compiler and code generator


오늘은 간단히 gsoap을 이용하여 사칙 연산을 해보도록 하겠다.


1. wsdl2h -s -o calc.h http://www.genivia.com/calc.wsdl

==> calc.wsdl 를 참고하여 calc.h 를 생성한다. 데이터 구조..


2. soapcpp2 -i -C calc.h

==>  여러 파일들이 생성될 것이다. xml, proxy 파일, soap 정의 등


3. test.c 만들기

#include "soapcalcProxy.h" 
#include "calc.nsmap" 
int main() 

   calcProxy service; 
   double result; 
   if (service.add(1.0, 2.0, result) == SOAP_OK) 
      std::cout << "The sum of 1.0 and 2.0 is " << result << std::endl; 
   else
      service.soap_stream_fault(std::cerr); 
   service.destroy(); // delete data and release memory 
}


test.cpp로 저장하고

g++ test.cpp soapcalcProxy.cpp soapC.cpp -lgsoap++ 로 컴파일 하면 끝...

간단하다.


4. ./a.out 실행 결과

calc3$ ./a.out 

The sum of 1.0 and 2.0 is 3







저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
[C Programming] Struct Hack  (0) 2013.08.15
Software Versioning (소프트웨어 버전규칙)  (0) 2013.08.07
Posted by sound79 사운드친구

댓글을 달아 주세요

간단히....

stub은 클라이언트에 위치

skeleton 은 서버에 위치한다고 보면 된다.


JAVA의 RMI를 기준으로 아래 원문을 참조해 보자


원문:

The rmic compiler generates two files: a stub and a skeleton. The stub resides on the client machine and the skeleton resides on the server machine. The stub and skeleton are comprised of Java code that provides the necessary link between the two objects.

When a client invokes a server method, the JVM looks at the stub to do type checking (since the class defined within the stub is an image of the server class). The request is then routed to the skeleton on the server, which in turn calls the appropriate method on the server object. In other words, the stub acts as a proxy to the skeleton and the skeleton is a proxy to the actual remote method.


참조

http://www.tns.lcs.mit.edu/manuals/java-rmi-alpha2/rmi-spec/rmi-arch.doc.html

http://theweak.tistory.com/entry/STUB%EC%8A%A4%ED%85%81-%EA%B3%BC-SKELETON%EC%8A%A4%EC%BC%88%EB%A0%88%ED%86%A4

저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
[C Programming] Struct Hack  (0) 2013.08.15
Software Versioning (소프트웨어 버전규칙)  (0) 2013.08.07
Posted by sound79 사운드친구

댓글을 달아 주세요


먼저 다음의 구조체에 대해서 어떻게 생각하는가요?...


struct SHack

{

int A;

int B;

char array[0];

} ;


컴파일시 char array[0] 와 같은 배열의 실제 크기는 얼마로 할당될것인가? 결론부터 말하자면..

"Struct Hack"은 구조체에서 가변길이의 멤버를 사용하기 위한 테크닉이다.


실제 사용시 아래와 같이 먼저 메모리를 할당한 후 사용을 할 수 있다.

struct SHack *e = malloc(sizeof(*e) + sizeof(char) + ARRAY_SIZE);


이는 다음과 같은 구조체와 같다.

 struct SHack

{

int A;

int B;

char array[ARRAY_SIZE];

};


gcc 는 이와 같은 메모리를  A, B 에 이어서  array를 연속적으로 할당하게 된다.


그럼 이의 장점은 무엇일까?. 간단히  char *array;로 선언한 다음  runtime에서 해당 부분만 malloc해서 사용하면 되지 않을까???


장점. 분명히 있다.

1. 이전에 언급했듯이 메모리가 연속적으로 되어 있다. 이는 해당 구조체를 포함한 데이터 전체  Copy시

다음과 같이 한번에 할 수 있다.

memcpy(dst, e, sizeof(*e) + ARRAY_SIZE);


2. 프로토콜을 처리하는 부분에서 적절히 사용할 수 가 있다. 조금만 생각해 보면 답 나올듯 하다. 실제 그렇게 많이 사용하고 있다.



참고로 C99에서는 "flexible array members" 로 명칭되어 있다. 바로 "struct hack" 불리어지던 테크닉을 말이다.

저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
[C Programming] Struct Hack  (0) 2013.08.15
Software Versioning (소프트웨어 버전규칙)  (0) 2013.08.07
Posted by sound79 사운드친구

댓글을 달아 주세요

Software를 개발하다 보면  Release가 될때쯤이면 언제나 신경 쓰이는 부분이 버전이다.

한번 배포하고 끝내는 거라면 그냥 1.0 혹은 버전없이 해도 되겠지만, 과연 그러한 S/W가 있을 것인가???

앞으로 계속 신규 기능을 추가해야 될것이고 계속적인 패치 또한 이루어져야 한다. 그러므로 의미 있는 버전을 고민하게 된다. 물론 현재 자신의 소속에서 정형화된 소프트웨어 버전 규칙이 존재할 것이다.


구글링에 검색해 보니... Wikipedia, Stackoverflow에 괜찮은 내용이 있어서 아래 링크.

http://en.wikipedia.org/wiki/Software_versioning

http://stackoverflow.com/questions/2864448/best-practice-software-versioning


앞으로 내가 정한 규칙은 아래 2가지 중에서 하나로 정해야 겠다.



S/W 버전이 x.y.z일 경우에.


  • x = major release
  • y = minor release
  • z = build number

혹은

  • x = main version number
  • y = feature number
  • z = hotfix number


2가지 중에서 굳이 고르라고 한다면 후자를 선택해야 겠다.


저작자 표시 비영리 동일 조건 변경 허락
신고

'Programming' 카테고리의 다른 글

현재 네트워크에서 DHCP 서버가 동작되고 있는지 확인?  (0) 2014.08.18
gsoap (2)  (1) 2014.03.12
gsoap (1)  (0) 2014.03.11
stub & skeleton 이해하기  (0) 2013.10.28
[C Programming] Struct Hack  (0) 2013.08.15
Software Versioning (소프트웨어 버전규칙)  (0) 2013.08.07
Posted by sound79 사운드친구

댓글을 달아 주세요