- 메세지를 한번 주고 받고 세션을 종료하는 클라이언트 소켓
- boost::asio 라이브러리 사용 (boost 의 date_time, thread, system 컴파일 필요)
- boost::asio::deadline_timer 를 이용하여 timeout 기능 구현 
- 비동시 소켓으로 구현한 동기 소켓(?)



#pragma once

#include <algorithm>
using namespace std;

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

using boost::asio::ip::tcp;


struct IsEOF_Basic
{
bool operator()(const std::string &)
{
return true;
}
};



template <class Ty = IsEOF_Basic>
class ClientSocket 
{
public:
ClientSocket() : socket_(io_service_), timeout_(io_service_), nResponse_(0) {}

~ClientSocket() 
{
Close();
}

bool Connect(const string &sIP, const string &sPort) 
{
bool bResult = false;

tcp::resolver resolver(io_service_);
tcp::resolver::query query(tcp::v4(), sIP, sPort);
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;

boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket_.close();
socket_.connect(*endpoint_iterator++, error);
}

if (!error) {
bResult = true;
}
return bResult;
}

void Send(const string &s, const int nTimeout = 5)
{
copy(s.begin(), s.end(), szBuff);

socket_.async_write_some(boost::asio::buffer(szBuff, s.length()),
boost::bind(&ClientSocket::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

timeout_.expires_from_now(boost::posix_time::seconds(nTimeout));
timeout_.async_wait(boost::bind(&ClientSocket::Timeout, this));

handle_read_wait();
}

int WaitForResponse()
{
socket_.io_service().reset();

while (socket_.io_service().run_one()) 
{
if (nResponse_) break;
}

return nResponse_;
}

void Close()
{
socket_.close();
}

std::string GetReadBuffer()
{
return sReadBuff_;
}

enum { TIMEOUT = -1, READY = 0, SUCCESS = 1 };

private:
void Timeout()
{
nResponse_ = TIMEOUT;
}

void handle_read_wait() 
{
socket_.async_read_some(boost::asio::buffer(szBuff, BUFF_SIZE),
boost::bind(&ClientSocket::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));

nResponse_ = READY;
}

void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
if (error) {
Close();
return;
}

sReadBuff_.append(szBuff, szBuff + bytes_transferred);

if (IsEOF(sReadBuff_)) {
nResponse_ = SUCCESS;
}
else {
handle_read_wait();
}
}

void handle_write(const boost::system::error_code& error, size_t bytes_transferred)
{
if (error) {
Close();
return;
}
}

private:
boost::asio::io_service io_service_;

boost::asio::deadline_timer timeout_;
tcp::socket socket_;
std::string sReadBuff_;
volatile int nResponse_;

Ty IsEOF;
enum { BUFF_SIZE = 8192};
char szBuff[BUFF_SIZE];
};

int SendPacket (
LPCSTR strIP, LPCSTR strPort, int nTimeoutSecond, LPCSTR szMessage, LPSTR szRetMessage)
{
int nResult = -2;

try {
typedef ClientSocket<> ClientSocketType;
ClientSocketType socket;

if (!socket.Connect(strIP, strPort)) {
throw -1;
}

if (nTimeoutSecond == 0) nTimeoutSecond = 5;

socket.Send(szMessage, nTimeoutSecond);
int nResponse = socket.WaitForResponse();

if (nResponse == ClientSocketType::TIMEOUT) {
throw 0;
}

if (nResponse == ClientSocketType::SUCCESS) {
std::string s = socket.GetReadBuffer();
std::copy(s.begin(), s.end(), szRetMessage);

nResult = s.size();
}
}
catch (int nErr) {
nResult = nErr;
}
catch (...) {}

return nResult;
}



'Dev > C++' 카테고리의 다른 글

[C++11] Variadic template  (0) 2014.11.02
boost 설치  (0) 2013.11.20
이미지 변환 모듈 (모바일용, GDI+)  (0) 2010.06.22
C++0x, RValue Reference  (0) 2009.05.27
C++0x Lambda  (0) 2009.05.20
http://sourceforge.net/projects/asio/

asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach.


asio 는 클로스 플랫폼은 지원하는 네트워크 라이브러리이다

ACE와는 비교도 안되게 가볍고 C++ 헤더로만 이루어져 있어 별도의 라이브러리 컴파일 과정이 필요없다.
그리고 각 플랫폼에 맞는 동기/비동기 모델을 하나의 인터페이스로 구현을 하여 유연성있는 네트워크 프로그램을 제공을 한다

boost 1.35부터 포함되어 있어 boost 라이브러리를 통해서 사용가능하고 직접 다운받아 stand alone 으로도  사용 가능하다


Download 쪽 항목을 보면 asio-tr2 라고 하는 패키지가 보이는데,
C++ tr2의 네트워크 라이브러리에 대한 제안서로 보인다.

개인적으로 tr2에 정의되어 있는 네트워크 라이브러리의 C++ 구현 인터페이스가 무지 궁금하지만,
asio 를 채택하는것도 그리 나쁜 선택은 아니라고 판단된다.


ps.
tr2의 내용중에 XML, HTML, Networking 같은 경우는 boost와 같이 C++ 계에서 주도적(?)으로
사용되는 것이 없어서 어떤 것들이 채택(혹은 구현)될지 궁금하다.

tr2의 주 내용
Unicode
XML and HTML
Networking
Usability for novices and occasional programmers


'Dev > C++' 카테고리의 다른 글

C++ Refactoring  (0) 2009.04.14
An Overview of the Coming C++ (C++0x) Standard  (0) 2008.12.29
C++ 0x - Herb Sutter의 블로그 글  (0) 2008.07.29
C++ 0x  (0) 2008.05.09
memory pooling - code  (0) 2008.05.01

출처 : http://boost.org/doc/html/boost_tr1/usage.html

boost 1.34 버전 이상 부터 지원

std::tr1 내용 :

Reference Wrappers.
Smart Pointers.
Class template result_of.
Function template mem_fn.
Function Object Binders.
Polymorphic function wrappers.
Type Traits.
Random Number Generators and Distributions.
Tuples.
Tuple Interface to std::pair.
Fixed Size Array.
Hash Function Objects.
Regular Expressions.
Complex Number Algorithm Overloads.
Complex Number Additional Algorithms.




Header Include Style

There are two ways you can include the Boost.TR1 headers, for example if you are interested in shared_ptr then you can either use:

#include <boost/tr1/memory.hpp>

or:

#include <memory>

The first option is the preferred method for other Boost libraries to use. The second option is standard-conforming, but requires that you add boost-install-path/boost/tr1/tr1 to your compiler's include search path. Note that you must not copy the headers in boost/tr1/tr1 into a directory called "include", doing so will cause them to cease working.


Important Note #1


The include path order is very important if you want this library to work correctly. If you get compiler errors then suspect the include paths. The correct order is:

1) boost-root/boost/tr1/tr1
2) boost-root
3) Any other standard library replacements (STLport for example).
4) Your regular standard library.

Important Note #2: Borland C++ Users


Borland's compiler has a particularly broken form of #include, that will actually look for a file named array.h if you #include <array>. In order to make this library work with Borland's compiler you will need to set up the include paths as follows:

1) boost-root/boost/tr1/tr1/bcc32
2) boost-root/boost/tr1/tr1
3) boost-root
4) Any other standard library replacements (STLport for example).
5) Your regular standard library.

Important Note #3: Sun C++ Users

Sun's compiler has a particularly interesting form of #include, that will actually look for a file named array.SUNWCCh if you #include <array>. In order to make this library work with Sun's compiler you will need to set up the include paths as follows:

1) boost-root/boost/tr1/tr1/sun
2) boost-root/boost/tr1/tr1
3) boost-root
4) Any other standard library replacements (STLport for example).
5) Your regular standard library.

'Dev > C++' 카테고리의 다른 글

main function  (0) 2008.05.01
tr1::regex (boost::regex) 샘플코드  (0) 2007.10.21
VC++ 2005 배포  (0) 2007.06.22
Unhandled C++ Exceptions  (0) 2007.06.19
OutputDebugString  (0) 2007.05.23

+ Recent posts