[ create a new paste ] login | about

Link: http://codepad.org/fyGO5lU6    [ raw code | fork ]

C++, pasted on Feb 13:
// 
// なんとなくTCPクライアント by ミングスレの名無し
// 
// ※注意:未テスト。多分動く気がするが、未テスト
//     見て理解出来る&バグあっても対処できる人向け(なのでコメント無し)
// 
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <queue>

// tcp::iostream に wchar_t!と思ったが良く考えたら意味が無いのでASCIIで
#ifdef UNICODE___
#include <xstring>
typedef std::wstring tstring;
#else
#include <string>
typedef std::string tstring;
#endif

// --------------------------------------------------
#define boost_ip boost::asio::ip
typedef boost_ip::address asio_ip;
typedef boost::mutex::scoped_lock lock;

#define boost_tcp boost_ip::tcp
typedef boost_tcp::iostream tcp_stream;

typedef bool (*Callback)(tstring &res);
typedef std::pair<tstring, Callback> _pv;
typedef std::queue<_pv> q_tstr;

// クライアント -----------------
class _TcpClient {
	boost::thread *th;
	boost::mutex mtx;
	q_tstr buf;

	asio_ip _ip;
	int _port;

	bool run;
	void sendThis(_pv &pv);
	void _threadRun();
public:
	_TcpClient();
	~_TcpClient();
	bool openConnection(asio_ip &ip, int port);
	bool send(tstring &msg, Callback func);
	bool closeConnection();
};

// --------------------------------------------------
#define _GET_STR(p) ((p).first)
#define _IF_CALLBACK(p) if((p).second != NULL)
#define _CALLBACK(p, s) ((p).second)(s)
#define _NOW() boost::get_system_time()

// --------------------------------------------------
_TcpClient::_TcpClient() : th(NULL)
{
}

_TcpClient::~_TcpClient()
{
	run = false;

	th->join();
	delete th;
	th = NULL;
}

void _TcpClient::sendThis(_pv &pv)
{
	tcp_stream out(boost_tcp::endpoint(_ip, _port));
	out << _GET_STR(pv) << std::flush;
	
	std::string tmp;
	_IF_CALLBACK(pv)
	{
		while(std::getline(out, tmp)) _CALLBACK(pv, tmp);
	}
}

void _TcpClient::_threadRun()
{
	boost::system_time ed = _NOW() + boost::posix_time::minutes(1);
	while(run)
	{
		if(_NOW() > ed) break;

		boost::thread::sleep(
			boost::get_system_time()
			+ boost::posix_time::milliseconds(50)
		);

		lock l(mtx);
		if(!buf.empty()) 
		{
			sendThis(buf.front());
			buf.pop();
			ed = _NOW() + boost::posix_time::minutes(1);
		}
	}

	// if(run) /* time-out */
	run = false;
}

bool _TcpClient::openConnection(asio_ip &ip, int port)
{
	if(th != NULL) return false;

	_ip = ip;
	_port = port;

	boost::function<void (void)> f = boost::bind(&_TcpClient::_threadRun, this);
	th = new boost::thread(f);

	return true;
}

bool _TcpClient::send(tstring &msg, Callback func)
{
	lock l(mtx);
	buf.push(_pv(msg, func));
	return true;
}

bool _TcpClient::closeConnection()
{
	run = false;
	return true;
}


Create a new paste based on this one


Comments: