2014年5月20日 星期二

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"]]

請按任意鍵繼續 . . .




沒有留言:

張貼留言

文章分類