2014年5月20日 星期二

msgpack sample source code ---(2) create customized class by map key

sockserver.cpp


#include <stdio.h>
//#include <winsock.h>
#include <msgpack.hpp>
#include <vector>
#include <string>
#include <iostream>

// Function prototype
void StreamServer3(short nPort);

// Helper macro for displaying errors
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

void main(int argc, char **argv)
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Check for port argument
//
if (argc != 2)
{
fprintf(stderr,"\nSyntax: server PortNumber\n");
return;
}

nPort = atoi(argv[1]);

//
// Initialize WinSock and check version
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}


//
// Do the stuff a stream server does
//
StreamServer3(nPort);


//
// Release WinSock
//
WSACleanup();
}


class MSGREQ_020
{
private:
public:
int iSeq;
std::string strSvcType;
int iReqMax;

MSGREQ_020():iSeq(0),strSvcType(""),iReqMax(0){}
MSGREQ_020(const int s,const std::string & st,  const int max):iSeq(s),strSvcType(st),iReqMax(max){}

MSGPACK_DEFINE(iSeq , strSvcType , iReqMax);
};

class MSGRSP_021
{
private:
public:
int iSeq;
std::vector<std::string> vecServers;

MSGRSP_021():iSeq(0){}
MSGRSP_021(const int s):iSeq(s){}

    MSGPACK_DEFINE(iSeq ,vecServers);
};

void StreamServer3(short nPort)
{
//
// Create a TCP/IP stream socket to "listen" with
//
SOCKET listenSocket;

listenSocket = socket(AF_INET, // Address family
 SOCK_STREAM, // Socket type
 IPPROTO_TCP); // Protocol
if (listenSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}


//
// Fill in the address structure
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = INADDR_ANY; // Let WinSock supply address
saServer.sin_port = htons(nPort); // Use port from command line

//
// bind the name to the socket
//
int nRet;

nRet = bind(listenSocket, // Socket 
(LPSOCKADDR)&saServer, // Our address
sizeof(struct sockaddr));// Size of address structure
if (nRet == SOCKET_ERROR)
{
PRINTERROR("bind()");
closesocket(listenSocket);
return;
}

//
// This isn't normally done or required, but in this 
// example we're printing out where the server is waiting
// so that you can connect the example client.
//
int nLen;
nLen = sizeof(SOCKADDR);
char szBuf[4096];

nRet = gethostname(szBuf, sizeof(szBuf));
if (nRet == SOCKET_ERROR)
{
PRINTERROR("gethostname()");
closesocket(listenSocket);
return;
}

//
// Show the server name and port number
//
printf("\nServer named %s waiting on port %d\n",
szBuf, nPort);

//
// Set the socket to listen
//

printf("\nlisten()");
nRet = listen(listenSocket, // Bound socket
SOMAXCONN); // Number of connection request queue
if (nRet == SOCKET_ERROR)
{
PRINTERROR("listen()");
closesocket(listenSocket);
return;
}

//
// Wait for an incoming request
//
SOCKET remoteSocket;

printf("\nBlocking at accept()\n\n");
remoteSocket = accept(listenSocket,  // Listening socket
NULL, // Optional client address
NULL);
if (remoteSocket == INVALID_SOCKET)
{
PRINTERROR("accept()\n\n");
closesocket(listenSocket);
return;
}

//
// We're connected to a client
// New socket descriptor returned already
// has clients address

//
// Receive data from the client
//
memset(szBuf, 0, sizeof(szBuf));
nRet = recv(remoteSocket, // Connected client
szBuf, // Receive buffer
sizeof(szBuf), // Length of buffer
0); // Flags
if (nRet == INVALID_SOCKET)
{
PRINTERROR("recv()");
closesocket(listenSocket);
closesocket(remoteSocket);
return;
}


// feeds the buffer.
char *pszContent = &szBuf[3];
int nContentLen = nRet-5;
    msgpack::unpacked  msg;
    msgpack::unpack(&msg, pszContent, nContentLen);

    msgpack::object  obj = msg.get();

    msgpack::object_kv*  pkv;
    msgpack::object_kv*  pkv_end;
    msgpack::object      pk, pv;
MSGREQ_020 msg_020;
//
// Display received data
//

    if(obj.via.map.size > 0)
    {
        pkv = obj.via.map.ptr;
        pkv_end = obj.via.map.ptr + obj.via.map.size;

std::string key;
pkv->key.convert (&key);
pkv->val.convert (&msg_020);
}

//
// Send data back to the client
//

char szBuf2[4096];
MSGRSP_021 msg_021;
unsigned short *len = (unsigned short *)&szBuf2[1];
szBuf2[0]=0x02;

msg_021.iSeq = msg_020.iSeq;
msg_021.vecServers.push_back("fdt00.com.tw");

    msgpack::sbuffer  sbuf;
    msgpack::packer<msgpack::sbuffer>   pker(&sbuf);

    pker.pack_map(1);
    pker.pack(std::string("021"));
    pker.pack(msg_021);
memcpy(&szBuf2[3],sbuf.data(), sbuf.size());
*len=sbuf.size(); 
szBuf2[3+ sbuf.size()]=0;


for(int jj = 0 ; jj < (sbuf.size()+3) ; jj++)
{
if(jj > 2)
szBuf2[3+ sbuf.size()] ^= szBuf2[jj];

}
szBuf2[3+sbuf.size()+1]=0x03;



nRet = send(remoteSocket, // Connected socket
szBuf2, // Data buffer
sbuf.size()+5, // Length of data
0); // Flags

//
// Close BOTH sockets before exiting
//
closesocket(remoteSocket);
     closesocket(listenSocket);
return;
}


sockclient.cpp


//msgpack not allow data aliment as pack(1), use default VC++ data aliment , pack(8)
//#pragma pack(push) /* push current alignment to stack */
//#pragma pack(8) /* set alignment to 1 byte boundary */
#include <stdio.h>
//#include <winsock.h>
#include <msgpack.hpp>
#include <vector>
#include <string>
#include <iostream>
//#pragma pack(pop) /* restore original alignment from stack */
// Function prototype
void StreamClient3(char *szServer, short nPort);

// Helper macro for displaying errors
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

void main(int argc, char **argv)
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Check for the host and port arguments
//
if (argc != 3)
{
fprintf(stderr,"\nSyntax: client ServerName PortNumber\n");
return;
}

nPort = atoi(argv[2]);


//
// Initialize WinSock and check the version
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}


//
// Go do the stuff a stream client does
//
StreamClient3(argv[1], nPort);

//
// Release WinSock
//
WSACleanup();
}



class MSGREQ_020
{
private:
public:
int iSeq;
std::string strSvcType;
int iReqMax;

MSGREQ_020():iSeq(0),strSvcType(""),iReqMax(0){}
MSGREQ_020(const int s,const std::string & st,  const int max):iSeq(s),strSvcType(st),iReqMax(max){}

MSGPACK_DEFINE(iSeq , strSvcType , iReqMax);
};

class MSGRSP_021
{
private:
public:
int iSeq;
std::vector<std::string> vecServers;

MSGRSP_021():iSeq(0){}
MSGRSP_021(const int s):iSeq(s){}

    MSGPACK_DEFINE(iSeq ,vecServers);
};
////////////////////////////////////////////////////////////


void StreamClient3(char *szServer, short nPort)
{
printf("\nStream Client connecting to server: %s on port: %d\n\n",
szServer, nPort);

//
// Find the server
//
    LPHOSTENT lpHostEntry;

lpHostEntry = gethostbyname(szServer);
    if (lpHostEntry == NULL)
    {
        PRINTERROR("gethostbyname()");
        return;
    }

//
// Create a TCP/IP stream socket
//
SOCKET theSocket;

theSocket = socket(AF_INET,// Address family
SOCK_STREAM,// Socket type
IPPROTO_TCP); // Protocol
if (theSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}

//
// Fill in the address structure
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET;

// Server's address
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
saServer.sin_port = htons(nPort); // Port number from command line

//
// connect to the server
//
int nRet;

nRet = connect(theSocket, // Socket
(LPSOCKADDR)&saServer, // Server address
sizeof(struct sockaddr));// Length of server address structure
if (nRet == SOCKET_ERROR)
{
PRINTERROR("socket()");
closesocket(theSocket);
return;
}
/******************************************************
<0x02><length>[MessagePacket Content]<bccChecksum><0x03>
              -----------------------
Serialization

Serializtion:   pker.pack_map(1);
pker.pack(std::string("020"));  //key
pker.pack(msg_020); //your own class

******************************************************/
char szBuf2[4096];

MSGREQ_020 msg_020;
unsigned short *len = (unsigned short *)&szBuf2[1];
szBuf2[0]=0x02;

msg_020.iSeq = 2345;
msg_020.strSvcType = "sean";
msg_020.iReqMax=0;

    msgpack::sbuffer  sbuf;
    msgpack::packer<msgpack::sbuffer>   pker(&sbuf);

    pker.pack_map(1);
    pker.pack(std::string("020"));
    pker.pack(msg_020);
memcpy(&szBuf2[3],sbuf.data(), sbuf.size());
*len=sbuf.size();   // length only for sbuf.data()
szBuf2[3+ sbuf.size()]=0;

// checksum only sbuf.data()
for(int jj = 0 ; jj < (sbuf.size()+3) ; jj++)  
{
if(jj > 2)
szBuf2[3+ sbuf.size()] ^= szBuf2[jj];

}
szBuf2[3+sbuf.size()+1]=0x03;


nRet = send(theSocket,// Connected socket
szBuf2, // Data buffer
sbuf.size()+5, // Length of data, head(3),tail(2,checksum+tail)
0); // Flags
/*******************************************************/
/*******************************************************/

if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
closesocket(theSocket);
return;
}

//
// Wait for a reply
//
char szBuf[4096];
nRet = recv(theSocket, // Connected socket
szBuf, // Receive buffer
sizeof(szBuf), // Size of receive buffer
0); // Flags
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recv()");
closesocket(theSocket);
return;
}


char *pszContent = &szBuf[3];
int nContentLen = nRet-5;
    msgpack::unpacked  msg;
    msgpack::unpack(&msg, pszContent, nContentLen);

    msgpack::object  obj = msg.get();

    msgpack::object_kv*  pkv;
    msgpack::object_kv*  pkv_end;
    msgpack::object      pk, pv;
MSGRSP_021 msg_021;
    if(obj.via.map.size > 0)
    {
        pkv = obj.via.map.ptr;
        pkv_end = obj.via.map.ptr + obj.via.map.size;

std::string key;
pkv->key.convert (&key);
pkv->val.convert (&msg_021);
for(int  kk=0 ; kk < msg_021.vecServers.size(); ++kk)
{
if(kk==0)
std::cout << key << "-->" << msg_021.iSeq << "," << msg_021.vecServers[kk] << std::endl;
else
std::cout <<"   -->    ," << msg_021.vecServers[kk] << std::endl;
}
}


//
// Display the received data
//



closesocket(theSocket);

system("PAUSE");
return;
}


執行結果:


Stream Client connecting to server: 127.0.0.1 on port: 5000

021-->2345,fdt00.com.tw
請按任意鍵繼續 . . .



msgpack sample source code ---(1) msgpack with customized class


sockserver.cpp



#include <stdio.h>
//#include <winsock.h>
#include <msgpack.hpp>
#include <vector>
#include <string>
#include <iostream>

// Function prototype
void StreamServer2(short nPort);

// Helper macro for displaying errors
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

void main(int argc, char **argv)
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Check for port argument
//
if (argc != 2)
{
fprintf(stderr,"\nSyntax: server PortNumber\n");
return;
}

nPort = atoi(argv[1]);

//
// Initialize WinSock and check version
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}


//
// Do the stuff a stream server does
//
StreamServer2(nPort);


//
// Release WinSock
//
WSACleanup();
}


class MSGREQ_020
{
private:
public:
int iSeq;
std::string strSvcType;
int iReqMax;

MSGREQ_020():iSeq(0),strSvcType(""),iReqMax(0){}
MSGREQ_020(const int s,const std::string & st,  const int max):iSeq(s),strSvcType(st),iReqMax(max){}

MSGPACK_DEFINE(iSeq , strSvcType , iReqMax);
};

class MSGRSP_021
{
private:
public:
int iSeq;
std::vector<std::string> vecServers;

MSGRSP_021():iSeq(0){}
MSGRSP_021(const int s):iSeq(s){}

    MSGPACK_DEFINE(iSeq ,vecServers);
};

void StreamServer2(short nPort)
{
//
// Create a TCP/IP stream socket to "listen" with
//
SOCKET listenSocket;

listenSocket = socket(AF_INET, // Address family
 SOCK_STREAM, // Socket type
 IPPROTO_TCP); // Protocol
if (listenSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}


//
// Fill in the address structure
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = INADDR_ANY; // Let WinSock supply address
saServer.sin_port = htons(nPort); // Use port from command line

//
// bind the name to the socket
//
int nRet;

nRet = bind(listenSocket, // Socket 
(LPSOCKADDR)&saServer, // Our address
sizeof(struct sockaddr));// Size of address structure
if (nRet == SOCKET_ERROR)
{
PRINTERROR("bind()");
closesocket(listenSocket);
return;
}

//
// This isn't normally done or required, but in this 
// example we're printing out where the server is waiting
// so that you can connect the example client.
//
int nLen;
nLen = sizeof(SOCKADDR);
char szBuf[4096];

nRet = gethostname(szBuf, sizeof(szBuf));
if (nRet == SOCKET_ERROR)
{
PRINTERROR("gethostname()");
closesocket(listenSocket);
return;
}

//
// Show the server name and port number
//
printf("\nServer named %s waiting on port %d\n",
szBuf, nPort);

//
// Set the socket to listen
//

printf("\nlisten()");
nRet = listen(listenSocket, // Bound socket
SOMAXCONN); // Number of connection request queue
if (nRet == SOCKET_ERROR)
{
PRINTERROR("listen()");
closesocket(listenSocket);
return;
}

//
// Wait for an incoming request
//
SOCKET remoteSocket;

printf("\nBlocking at accept()\n\n");
remoteSocket = accept(listenSocket,  // Listening socket
NULL, // Optional client address
NULL);
if (remoteSocket == INVALID_SOCKET)
{
PRINTERROR("accept()\n\n");
closesocket(listenSocket);
return;
}

//
// We're connected to a client
// New socket descriptor returned already
// has clients address

//
// Receive data from the client
//
memset(szBuf, 0, sizeof(szBuf));
nRet = recv(remoteSocket, // Connected client
szBuf, // Receive buffer
sizeof(szBuf), // Length of buffer
0); // Flags
if (nRet == INVALID_SOCKET)
{
PRINTERROR("recv()");
closesocket(listenSocket);
closesocket(remoteSocket);
return;
}


msgpack::unpacked msg;
msgpack::unpack(&msg, &szBuf[6], (size_t)nRet-8);

msgpack::object obj = msg.get();

MSGREQ_020 rvec;
obj.convert(&rvec);
std::cout << obj << std::endl;


// feeds the buffer.

/******************************************************
<0x02><length>[pt] [MessagePacket Content]<bccChecksum><0x03>
              ---  -----------------------
              X(3)  Serialization
******************************************************/
char szBuf2[4096];
unsigned short *len = (unsigned short *)&szBuf2[1];
MSGRSP_021 msg_021;
szBuf2[0]=0x02;

msg_021.iSeq = rvec.iSeq;
msg_021.vecServers.push_back("fdt01.com.tw");
msg_021.vecServers.push_back("fdt99.com.tw");

msgpack::sbuffer sbuf;
msgpack::pack(sbuf, msg_021);

memcpy(&szBuf2[3] , "021" , 3);
memcpy(&szBuf2[6],sbuf.data(), sbuf.size());
*len=sbuf.size()+3; // len(2)+checksum(1)
szBuf2[6+ sbuf.size()]=0;


for(int jj = 0 ; jj < (sbuf.size()+6) ; jj++)
{
if(jj > 2)
szBuf2[6+ sbuf.size()] ^= szBuf2[jj];
}
szBuf2[6+sbuf.size()+1]=0x03;
nRet = send(remoteSocket,// Connected socket
szBuf2, // Data buffer
sbuf.size()+8, // Length of data, head(3),pt(3),tail(2,checksum+tail)
0); // Flags
/*******************************************************/
/*******************************************************/


//
// Close BOTH sockets before exiting
//
closesocket(remoteSocket);
     closesocket(listenSocket);
return;
}


sockclient.cpp



//msgpack is not allow data aliment as pack(1), advised as pack(8), VC++ default
//#pragma pack(push) /* push current alignment to stack */
//#pragma pack(8) /* set alignment to 1 byte boundary */
#include <stdio.h>
//#include <winsock.h>
#include <msgpack.hpp>
#include <vector>
#include <string>
#include <iostream>
//#pragma pack(pop) /* restore original alignment from stack */
// Function prototype
void StreamClient2(char *szServer, short nPort);

// Helper macro for displaying errors
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

void main(int argc, char **argv)
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Check for the host and port arguments
//
if (argc != 3)
{
fprintf(stderr,"\nSyntax: client ServerName PortNumber\n");
return;
}

nPort = atoi(argv[2]);


//
// Initialize WinSock and check the version
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}


//
// Go do the stuff a stream client does
//
StreamClient2(argv[1], nPort);

//
// Release WinSock
//
WSACleanup();
}



class MSGREQ_020
{
private:
public:
int iSeq;
std::string strSvcType;
int iReqMax;

MSGREQ_020():iSeq(0),strSvcType(""),iReqMax(0){}
MSGREQ_020(const int s,const std::string & st,  const int max):iSeq(s),strSvcType(st),iReqMax(max){}

MSGPACK_DEFINE(iSeq , strSvcType , iReqMax);
};

class MSGRSP_021
{
private:
public:
int iSeq;
std::vector<std::string> vecServers;

MSGRSP_021():iSeq(0){}
MSGRSP_021(const int s):iSeq(s){}

    MSGPACK_DEFINE(iSeq ,vecServers);
};
////////////////////////////////////////////////////////////

void StreamClient2(char *szServer, short nPort)
{
printf("\nStream Client connecting to server: %s on port: %d\n\n",
szServer, nPort);

//
// Find the server
//
    LPHOSTENT lpHostEntry;

lpHostEntry = gethostbyname(szServer);
    if (lpHostEntry == NULL)
    {
        PRINTERROR("gethostbyname()");
        return;
    }

//
// Create a TCP/IP stream socket
//
SOCKET theSocket;

theSocket = socket(AF_INET,// Address family
SOCK_STREAM,// Socket type
IPPROTO_TCP); // Protocol
if (theSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}

//
// Fill in the address structure
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET;

// Server's address
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
saServer.sin_port = htons(nPort); // Port number from command line

//
// connect to the server
//
int nRet;

nRet = connect(theSocket, // Socket
(LPSOCKADDR)&saServer, // Server address
sizeof(struct sockaddr));// Length of server address structure
if (nRet == SOCKET_ERROR)
{
PRINTERROR("socket()");
closesocket(theSocket);
return;
}
/******************************************************
<0x02><length>[pt] [MessagePacket Content]<bccChecksum><0x03>
              ---  -----------------------
              X(3)  Serialization
******************************************************/
char szBuf2[4096];
unsigned short *len = (unsigned short *)&szBuf2[1];
MSGREQ_020 msg_020;
szBuf2[0]=0x02;

msg_020.iSeq = 1234;
msg_020.strSvcType = "sean";
msg_020.iReqMax=1;

msgpack::sbuffer sbuf;
msgpack::pack(sbuf, msg_020);

memcpy(&szBuf2[3] , "020" , 3);
memcpy(&szBuf2[6],sbuf.data(), sbuf.size());
*len=sbuf.size()+3; // len(2)+checksum(1)
szBuf2[6+ sbuf.size()]=0;


//checksum
for(int jj = 0 ; jj < (sbuf.size()+6) ; jj++)
{
if(jj > 2)
szBuf2[6+ sbuf.size()] ^= szBuf2[jj];

}
szBuf2[6+sbuf.size()+1]=0x03;
nRet = send(theSocket, // Connected socket
szBuf2,  // Data buffer
sbuf.size()+8, // Length of data, head(3),pt(3),tail(2,checksum+tail)
0); // Flags
/*******************************************************/
/*******************************************************/

if (nRet == SOCKET_ERROR)
{
PRINTERROR("send()");
closesocket(theSocket);
return;
}

//
// Wait for a reply
//
char szBuf[4096];
nRet = recv(theSocket, // Connected socket
szBuf, // Receive buffer
sizeof(szBuf), // Size of receive buffer
0); // Flags
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recv()");
closesocket(theSocket);
return;
}

//
// Display the received data
//
msgpack::unpacked msg;
msgpack::unpack(&msg, &szBuf[6], (size_t)nRet-8);

msgpack::object obj = msg.get();

MSGRSP_021 rvec;
obj.convert(&rvec);
std::cout << obj << std::endl;


closesocket(theSocket);
system("PAUSE");
return;
}


執行結果:


Stream Client connecting to server: 127.0.0.1 on port: 5000

[1234, ["fdt01.com.tw", "fdt99.com.tw"]]

請按任意鍵繼續 . . .




文章分類