레이블이 asio인 게시물을 표시합니다. 모든 게시물 표시
레이블이 asio인 게시물을 표시합니다. 모든 게시물 표시

2010년 1월 21일 목요일

boost asio 를 이용 serialport 로 테스트용 바이트시퀀스를 줄줄이 싸봤다.

보드쪽에서 시리얼 읽는게 좀 이상하길래 만들어본 테스트 코드.

처음엔 haskell 로 짰는데( serialport 라고, haskell 에서 win32 시리얼 포트를 지원하는 라이브러리가 나온게 본기억이 나서 ) ㅋㅋㅋ 잘 안되더라. send 가 묘하게 느리던데.. 업무상 필요한 작업이라 삽질 그만두고 바로 C++ 로 짜버렸다.

테스트한 시나리오가.. C++ 로 0x00 부터 0xFF 를 줄기차게 날리고 보드쪽에서 매번 한바이트읽을때마다 기존 값하고 1 차이나는지 비교한.. 단순히 한방향 통신만 하는 코드라서 시리얼포트에서 읽거나 하는 코드는 들어있지 않다.

뭐 사실 그냥 asio 사용하고 다를거하나 없고 set_option 의 사용법 정도나 봐두면 되겠다.



#include <boost/asio.hpp>
#include <exception>
#include <iostream>

using namespace std;


int main()
{
try
{
boost::asio::io_service io_service;

// 시리얼포트 열고
boost::asio::serial_port s(io_service, "COM4");
boost::asio::serial_port::baud_rate baud_rate(9600);
s.set_option(baud_rate);

boost::asio::deadline_timer t(io_service);
unsigned char buf[1] = {0};

while(true)
{
// 한바이트씩 보내자
s.write_some(boost::asio::buffer(buf, sizeof(buf)));
cout << static_cast<unsigned int>(buf[0]) << endl;

// 0x00 부터 0xFF 까지 보내면 되겠지.
buf[0]++;

// 잠시 쉬자.
t.expires_from_now(boost::posix_time::milliseconds(5));
t.wait();
}


io_service.run();
}
catch(exception& e)
{
cerr << e.what() << endl;
}
}

2009년 4월 14일 화요일

boost::asio 로 만들어본 간단한 콘솔 서버 ( async_read_until 사용예 )

서버를 짜다보면 간단한 제어 인터페이스를 노출할 경우가 많은데 보통 웹을 붙이거나 shell 을 흉내낸다. 이하는 asio 로 간단히 shell 흉내를 내는 코드를 만들어본것.

그냥 시간이 남아 간단히 만들어본건데 async_read_until 때문에 조금 고생했다.
이놈이 받는 버퍼는 다른 async 류 함수들과 달리 streambuf 더라.
나는 평소 C++ 을 쓰더라도 stream 쪽은 전혀 쓰질 않아서 이쪽은 하나도 모르는데.. 그래서 좀 애먹었다. 급한대로 streambuf 로부터 한글자씩 꺼내서 처리해봤는데 이건 좀 아닌거 같고 좀더 나은 방법을 뒤져봐야겠다.


이하는 main 을 담고있는 코드.
한줄을 받아서 한줄을 내놓는 최소한의 로직만 담고있는 클래스 echo 를 정의하고 이놈으로 console<echo> 인스턴스를 만들어 io_service 에 붙였다. 당연히 그냥 asio 공부하려고 만들어본 코드니 제구실하기엔 부족한 코드.

main.cpp..


아래는 console, session 을 담고있는 코드
console<T> 는 그냥 acceptor 라고 보면 된다. 특정 포트로 tcp 받아서 session<T> 를 까주는 놈. session<T> 는.. 결국 session<echo> 로 인스턴스가 만들어지는데 echo 가 가진 함수를 부르기 위한 소켓관련 작업들을 해주는 놈이다.

console.hpp..


이건 include 모음집. 네임스페이스 처리가 짱나서 하나에 몰아두고 쓰는게 좋지.

boostasio.hpp..



음.
좀더 뒤져서 asio::streambuf 에서 값을 꺼내는 방법을 하나 더 찾았다.
        asio::const_buffer data = buf_.data();
        const char* b = asio::buffer_cast<const char*>(data);
        const char* e = b + readed;
뭐 대략 이런식인데 이것도 통쾌한 방법은 아닌거 같다. 문서상 그리고 메일링에서도 istream 을 통해 꺼내오는것을 권장하는거 같은데.. iostream 쪽 코드는 영 손대기 그렇구만..
그리고 이런식으로 뽑아쓸경우 consume 으로 버퍼 비워주는것도 잊지말자.


추가.
ReadHandler 같은경우 error 와 readed 를 인자로 받는데 나는 error 나면 readed 무시하고 바로 에러를 내도록 했지만 경우에 따라 readed 를 먼저 처리하고 error 확인해야 할때도 있을거 같은데.. 이건 나중에 asio 를 정말 쓰게되면 다시 만날 문제겠지.






2009년 4월 9일 목요일

boost::asio 를 이용한 tcp 연결 테스터 -- boost::bind 와 boost::function 을 이용해서 두 클래스의 의존성 줄이기

음 제목짓기가 애매하네.
어떤 서버가 tcp 연결을 몇개까지 받는지 테스트해야 했는데 어쩌다 보니 C++ 로 짜게 됐다.(ghc 의 소켓제한 때문에..)

워낙 간단한 코드라 평소 안하던짓을 한번 해보고 코드를 적어둔다.

소켓을 다룰때 많은 세션을 다루려면 이 세션을 다루는 매니저 클래스가 있을법 한데 보통 이경우 세션 클래스가 매니저 클래스를 알아야만 한다(커플링). 이걸 bind 와 function 으로 좀 오버해서 만들어봤다.

물론 이외에도 방법은 많고.. 실무에 써야 한다면 아마도 당연히 그냥 의존성을 그냥 두고 가거나 아니면 signal 류 라이브러리를 썼겠지. 아래 코드는 재미삼아 만들어본것에 불과하다.



펼쳐두기..


추가.
어쩌다보니 연결 받는놈도 필요해서 만들었다. 걍 같이 적어둔다.

펼쳐두기..