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"]]
請按任意鍵繼續 . . .
沒有留言:
張貼留言