mirror of
				https://github.com/msgpack/msgpack-c.git
				synced 2025-11-04 04:09:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			137 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <msgpack.hpp>
 | 
						|
#include <iostream>
 | 
						|
#include <stdexcept>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <pthread.h>
 | 
						|
 | 
						|
class Server {
 | 
						|
public:
 | 
						|
	Server(int sock) : m_sock(sock) { }
 | 
						|
 | 
						|
	~Server() { }
 | 
						|
 | 
						|
	typedef std::auto_ptr<msgpack::zone> auto_zone;
 | 
						|
 | 
						|
	void socket_readable()
 | 
						|
	{
 | 
						|
		m_pac.reserve_buffer(1024);
 | 
						|
 | 
						|
		ssize_t count =
 | 
						|
			read(m_sock, m_pac.buffer(), m_pac.buffer_capacity());
 | 
						|
 | 
						|
		if(count <= 0) {
 | 
						|
			if(count == 0) {
 | 
						|
				throw std::runtime_error("connection closed");
 | 
						|
			}
 | 
						|
			if(errno == EAGAIN || errno == EINTR) {
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			throw std::runtime_error(strerror(errno));
 | 
						|
		}
 | 
						|
 | 
						|
		m_pac.buffer_consumed(count);
 | 
						|
 | 
						|
		while(m_pac.execute()) {
 | 
						|
			msgpack::object msg = m_pac.data();
 | 
						|
 | 
						|
			auto_zone life( m_pac.release_zone() );
 | 
						|
 | 
						|
			m_pac.reset();
 | 
						|
 | 
						|
			process_message(msg, life);
 | 
						|
		}
 | 
						|
 | 
						|
		if(m_pac.message_size() > 10*1024*1024) {
 | 
						|
			throw std::runtime_error("message is too large");
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
private:
 | 
						|
	void process_message(msgpack::object msg, auto_zone& life)
 | 
						|
	{
 | 
						|
		std::cout << "message reached: " << msg << std::endl;
 | 
						|
	}
 | 
						|
 | 
						|
private:
 | 
						|
	int m_sock;
 | 
						|
	msgpack::unpacker m_pac;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
static void* run_server(void* arg)
 | 
						|
try {
 | 
						|
	Server* srv = reinterpret_cast<Server*>(arg);
 | 
						|
 | 
						|
	while(true) {
 | 
						|
		srv->socket_readable();
 | 
						|
	}
 | 
						|
	return NULL;
 | 
						|
 | 
						|
} catch (std::exception& e) {
 | 
						|
	std::cerr << "error while processing client packet: "
 | 
						|
		<< e.what() << std::endl;
 | 
						|
	return NULL;
 | 
						|
 | 
						|
} catch (...) {
 | 
						|
	std::cerr << "error while processing client packet: "
 | 
						|
		<< "unknown error" << std::endl;
 | 
						|
	return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
struct fwriter {
 | 
						|
	fwriter(int fd) : m_fp( fdopen(fd, "w") ) { }
 | 
						|
 | 
						|
	void write(const char* buf, size_t buflen)
 | 
						|
	{
 | 
						|
		size_t count = fwrite(buf, buflen, 1, m_fp);
 | 
						|
		if(count < 1) {
 | 
						|
			std::cout << buflen << std::endl;
 | 
						|
			std::cout << count << std::endl;
 | 
						|
			throw std::runtime_error(strerror(errno));
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	void flush() { fflush(m_fp); }
 | 
						|
 | 
						|
	void close() { fclose(m_fp); }
 | 
						|
 | 
						|
private:
 | 
						|
	FILE* m_fp;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
int main(void)
 | 
						|
{
 | 
						|
	int pair[2];
 | 
						|
	pipe(pair);
 | 
						|
 | 
						|
	// run server thread
 | 
						|
	Server srv(pair[0]);
 | 
						|
	pthread_t thread;
 | 
						|
	pthread_create(&thread, NULL,
 | 
						|
			run_server, reinterpret_cast<void*>(&srv));
 | 
						|
 | 
						|
	// client thread:
 | 
						|
	fwriter writer(pair[1]);
 | 
						|
	msgpack::packer<fwriter> pk(writer);
 | 
						|
 | 
						|
	typedef msgpack::type::tuple<std::string, std::string, std::string> put_t;
 | 
						|
	typedef msgpack::type::tuple<std::string, std::string> get_t;
 | 
						|
 | 
						|
	put_t req1("put", "apple", "red");
 | 
						|
	put_t req2("put", "lemon", "yellow");
 | 
						|
	get_t req3("get", "apple");
 | 
						|
	pk.pack(req1);
 | 
						|
	pk.pack(req2);
 | 
						|
	pk.pack(req3);
 | 
						|
	writer.flush();
 | 
						|
	writer.close();
 | 
						|
 | 
						|
	pthread_join(thread, NULL);
 | 
						|
}
 | 
						|
 |