diff options
author | Matthew Newhook <matthew@zeroc.com> | 2006-09-15 09:02:24 +0000 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2006-09-15 09:02:24 +0000 |
commit | 500fb11075408e45320d098e26914f251c3406d0 (patch) | |
tree | 564d9c6100e84e376fb2683c35f17091da49367f /perf/src/Ice/raw/cpp/Client.cpp | |
parent | Fixed TODOs (diff) | |
download | ice-500fb11075408e45320d098e26914f251c3406d0.tar.bz2 ice-500fb11075408e45320d098e26914f251c3406d0.tar.xz ice-500fb11075408e45320d098e26914f251c3406d0.zip |
added raw tests.
Diffstat (limited to 'perf/src/Ice/raw/cpp/Client.cpp')
-rwxr-xr-x | perf/src/Ice/raw/cpp/Client.cpp | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/perf/src/Ice/raw/cpp/Client.cpp b/perf/src/Ice/raw/cpp/Client.cpp new file mode 100755 index 00000000000..f4821c05991 --- /dev/null +++ b/perf/src/Ice/raw/cpp/Client.cpp @@ -0,0 +1,322 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define _CRT_SECURE_NO_DEPRECATE 1 // C4996 '<C function>' was declared deprecated/ +# pragma warning( 4 : 4996 ) // C4996 'std::<function>' was declared deprecated +#endif + +#ifdef _WIN32 +# include <winsock2.h> +typedef int ssize_t; +#else +# include <unistd.h> +# include <fcntl.h> +# include <sys/socket.h> + +# if defined(__hpux) +# include <sys/time.h> +# else +# include <sys/select.h> +# endif + +# include <netinet/in.h> +# include <netinet/tcp.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#ifdef _WIN32 +# include <sys/timeb.h> +#else +# include <sys/time.h> +#endif + +#ifndef _WIN32 +# define SOCKET int +# define SOCKET_ERROR -1 +# define INVALID_SOCKET -1 +#endif + +#include <iostream> +#include <string> + +using namespace std; + +namespace Protocol +{ + +// +// Size of the Ice protocol header +// +// Magic number (4 Bytes) +// Protocol version major (Byte) +// Protocol version minor (Byte) +// Encoding version major (Byte) +// Encoding version minor (Byte) +// Message type (Byte) +// Compression status (Byte) +// Message size (Int) +// +const int headerSize = 14; + +// +// The current Ice protocol and encoding version +// +const char protocolMajor = 1; +const char protocolMinor = 0; +const char encodingMajor = 1; +const char encodingMinor = 0; + +// +// The Ice protocol message types +// +const char requestMsg = 0; +const char requestBatchMsg = 1; +const char replyMsg = 2; +const char validateConnectionMsg = 3; +const char closeConnectionMsg = 4; + +// +// The request header, batch request header and reply header. +// + +const char magic[] = { 0x49, 0x63, 0x65, 0x50 }; // 'I', 'c', 'e', 'P' + +#ifdef __BCPLUSPLUS__ +const char requestHdr[headerSize + sizeof(Ice::Int)] = +#else +const char requestHdr[] = +#endif +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + encodingMajor, + encodingMinor, + requestMsg, + 0, // Compression status + 0, 0, 0, 0, // Message size (placeholder) + 0, 0, 0, 0 // Request id (placeholder) +}; + +#ifdef __BCPLUSPLUS__ +const char requestBatchHdr[headerSize + sizeof(Ice::Int)] = +#else +const char requestBatchHdr[] = +#endif +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + encodingMajor, + encodingMinor, + requestBatchMsg, + 0, // Compression status + 0, 0, 0, 0, // Message size (place holder) + 0, 0, 0, 0 // Number of requests in batch (placeholder) +}; + +const char replyHdr[] = +{ + magic[0], + magic[1], + magic[2], + magic[3], + protocolMajor, + protocolMinor, + encodingMajor, + encodingMinor, + replyMsg, + 0, // Compression status + 0, 0, 0, 0 // Message size (placeholder) +}; + +} + +int +putInt(char* base, int& offset, int v) +{ + memcpy(base + offset, &v, sizeof(int)); + offset += sizeof(int); +} + +int +getInt(char* base, int& offset) +{ + int v = *(int*)base; + offset += sizeof(int); + return v; +} + +void +run(SOCKET fd) +{ + int seq = 500000; + char req[seq + Protocol::headerSize + 42]; // 42 is the size of the message header + memset(req, 0, sizeof(req)); + memcpy(req, Protocol::requestHdr, Protocol::headerSize); + + int offset = 10; + putInt(req, offset, sizeof(req)); + putInt(req, offset, 0); // request id + string idName = "throughput"; + req[offset++] = (char)idName.size(); + memcpy(&req[offset], idName.c_str(), idName.size()); + offset += idName.size(); + + req[offset++] = 0; + req[offset++] = 0; // facet + + string opName = "sendByteSeq"; // operation name + req[offset++] = (char)opName.size(); + memcpy(&req[offset], opName.c_str(), opName.size()); + offset += opName.size(); + + req[offset++] = 0; // mode + req[offset++] = 0; // context + + // encapsulation for the sendByteSeq request data. + putInt(req, offset, 50011); + req[offset++] = Protocol::encodingMajor; + req[offset++] = Protocol::encodingMinor; + req[offset++] = (char)255; // number of elements. + putInt(req, offset, 50000); + + int requestId = 1; + char reply[25]; + char header[14]; + char magic[4]; + + // Read connection validation. + int len = 0; + int size = sizeof(header); + while(len != size) + { + int n = ::recv(fd, &header[len], size - len, 0); + if(n <= 0) + { + return; + } + len += n; + } + + // Process validation message. + assert(header[0] == Protocol::magic[0] && header[1] == Protocol::magic[1] && + header[2] == Protocol::magic[2] && header[3] == Protocol::magic[3]); + offset = 4; + + char pMajor = header[offset++]; + assert(pMajor == Protocol::protocolMajor); + //char pMinor = header[offset++]; + offset++; + + char eMajor = header[offset++]; + assert(eMajor == Protocol::encodingMajor); + //char eMinor = header[offset++]; + offset++; + + char messageType = header[offset++]; + assert(messageType == Protocol::validateConnectionMsg); + + //char compress = header[offset++]; + offset++; + size = getInt(header, offset); + +#ifdef WIN32 + struct _timeb tb; + _ftime(&tb); + __int64 start = tb.time * 1000000 + tb.millitm * 1000; +#else + struct timeval tv; + gettimeofday(&tv, 0); + long start = tv.tv_sec * 1000000 + tv.tv_usec; +#endif + + // Send some requests. First we want to "warm up" the JIT compiler. + int repetitions = 200; + for (int i = 0; i < repetitions; ++i) + { + // Request message body. + offset = 14; + putInt(req, offset, requestId); + ++requestId; + + if(::send(fd, req, sizeof(req), 0) != sizeof(req)) + { + return; + } + + len = 0; + size = sizeof(reply); + while(len != size) + { + int n = ::recv(fd, &reply[len], size-len, 0); + if(n <= 0) + { + return; + } + len += n; + } + } + +#ifdef WIN32 + _ftime(&tb); + float tm = (tb.time * 1000000 + tb.millitm * 1000 - start) / 1000.0f; +#else + gettimeofday(&tv, 0); + float tm = (tv.tv_sec * 1000000 + tv.tv_usec - start) / 1000; +#endif + cout << "time for " << repetitions << " sequences: " << (float) tm << "ms" << endl; + cout << "time per sequence: " << (float) tm / repetitions << "ms" << endl; +} + +int +main(int argc, char* argv[]) +{ +#ifdef _WIN32 + WORD version = MAKEWORD(1, 1); + WSADATA data; + if(WSAStartup(version, &data) != 0) + { + cerr << "WSAStartup failed!" << endl; + } +#endif + + char buffer[64]; + + SOCKET fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if(fd == INVALID_SOCKET) + { + cerr << "Create socket failed!" << endl; + return EXIT_FAILURE; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + addr.sin_port = htons(10000); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if(::connect(fd, reinterpret_cast<struct sockaddr*>(&addr), int(sizeof(addr))) == SOCKET_ERROR) + { + cerr << "Connect failed!" << endl; + return EXIT_FAILURE; + } + + run(fd); + + return EXIT_SUCCESS; +} |