Tuesday, December 30, 2008

Pasta



지난번에 토마토 소스를 부으려다가 까르보나라 소스를 부어버린 비운의 파스타.

그래서 다시 만들어서 먹어봤다.

익히는 시간은 조금 줄이고, 올리브 유에 볶는 시간을 늘렸더니

맛이 더 좋아진 듯 하다. 스파게티도 이렇게 한번 해봐야겠다.

재료 : 양파, 마늘, 버섯, 파스타, 베이컨, 녹색피망, 토마토소스, 케챱, 모챠렐라 치즈

2008년 마지막 날

2008년 마지막 날이다.

30살이 되기 전에 큰 변화를 주었다는 사실에 

스스로 만족하려고 하고 있다.

내년에도 열씸히 살아야지.


하나 소원이 있다면..

영어 좀 빨리 늘어라 제발. ㅠㅠ

Sunday, December 28, 2008

크리스마스 만찬

외쿡은 크리스마스를 엄청 중요하게 여기는 거 같다.
이곳저곳에서 파티, 클럽 러쉬가 발발.
하지만, 돈도 없고 클럽을 좋아하지도 않는 나에게는 먼 나라 이야기.

그래서 요리나 열씸히 했다. 후후후.
회사 친구인 주디양까지 자신의 요리를 해와서 배터지게 먹을 수 있었다.
이런 게 바로 파티, 만찬이지 뭐~ :)



주디양이 만들어온 치즈 케익.
치즈, 초콜렛, 딸기가 잘 어울려저서 상당히 맛있었다.
만드는 데 10시간이나 걸렸다고 함. 정성이 대단함!



왼쪽은 파스타 오른쪽은 스파게티.
베이컨, 버섯, 피망, 양파, 마늘 등 많은 재료를 사용.
소스도 까르보나라와, 토마토 소스 를 준비하는 등 다르게 하였으나!!!
원래는 스파게티를 까르보나라로 만들고 파스타를 토마토 소스로 만들려는 의도였지만
소스를 섞을 때 잘못 부어버렸다. -0-;
그래도 맛은 좋았으니 안심.



요건 샐러드와 빵집에서 사온 마늘빵.
걍 내가 한건 소스뿌리고 배치한 것 뿐. 하지만 잘 준비했다고 생각한다. 후훗.



나의 메인 요리. 순대 떡볶이!!!!
싱가폴 애들은 순대를 아예 몰라서, 그냥 떡볶이 보다는 순대 떡볶이가 낫다고 판단.
한국 슈퍼마켓에서 냉동순대 사와서 열씸히 만들었다. 크하핫.
아 지대로 맛있었다. 퀠퀠.
주디양이 좀 늦게 오는 바람에 순대가 다 터져버린 게 아쉬웠다. 하지만 맛은 최고~
재료값이 엄청 나게 든 순대 떡볶이였다.




최종 모습!
위에서 설명하지 않은 소고기 요리도 있으나, 그건 좀 허접하기 때문에 패스. :)

요리 열씸히 하고 다들 맛있게 먹고 나니까, 참 뿌듯하드라.
와인도 상당히 이름있는 Casillero del Diablo.
2008년 크리스마스 이브는 오래 기억에 남을 거 같다.

같이 만찬을 즐겨준 쌤형과 주디양께 감사를.

Casillero del Diablo 2006


It's one of the most famous wine brands from Chille.
The taste was also great.
I enjoyed this wine at Christmas eve.
This wine started the SELF - Christmas Party. :)

Anyway, you can find a lot of data from its web site.
The web site is also great. Good visual, lots of data.

One more.
'Reserva'. Its meaning is an aged wine.
Generally, the win has 'reserva', it should be aged 3 years, or 5 years, or over.
(It's up to the each wine aged method.)
But, we can find 'reserva' easily in Chile wines.
I think Chille wine would add 'reserva' to add an effect for a marketing and visual.

--------------------------------------------------

Name : Casillero del Diablo Cabernet Sauvignon
Country : Chille
Vintage : 2006
Style : Full bodied dry.
Colour : Red
Sweet : 3.4 / 5
Tannin : 4.3 / 5
Deep : 4.4 / 5
Price : 3.7 / 5 (SGD $33)

Overall : 4.1 / 5

Robert Mondavi Woodbridge 2006



The over is a little bit different from normal wine's.
Its top part is torn, like as a saw.

I think it is famous, wide and huge wine factory.
Probably lots of americans may enjoy it.

It's a first wine which I have enjoyed the wine from USA.
Each country's wine taste is all different.
The wine from the USA has its especialized taste.
It's enough for having a good time with a nice meal.

---------------------------------------------

Name : Robert Mondavi Woodbridge 2006 Cabernet Sauvignon
Country : USA / California
Vintage : 2006
Style : Full bodied dry
Colour : Red
Sweet : 3.9 / 5
Tannin : 3.2 / 5
Deep : 3.4 / 5
Price : 3.2 / 5 (SGD $23)

Overall : 3.4 /5

Tuesday, December 23, 2008

오늘부터 The end of the year holiday season

오늘부터 쉰다.
2009년 1월 5일에 다시 출근.
역시 외쿡인들은 깔끔하게 쉰단 말야.
이 기간에 앞뒤로 더해서 3, 4 주를 쉬는 사람들도 있음.
나도 내년에 짬이 좀 생기면 해보던가 해야지. 후후훗.

쉬는 동안에 내년 계획이나 잘 짜보고,
공부할 것도 정해 놓았다. 게으르지 말고 잘 지켜나가야겠다.

그건 그거고,
가족들에게 보낼 크리스마드 카드를 붙이려고 두번이나 우체국에 방문해주었지만
엄청난 큐 때문에 포기.....
이놈의 나라는 어딜가나 엄청난 큐가 많다.
무슨, 우체국안에 40명이 넘게 줄을 만들고 있냐고. TT

올해 크리스마스는 집에서 운동하면서 지낼듯.
그리고 집을 좀 알아봐야겠다.
너무 멀어서 힘들어죽겠네.

Sunday, December 21, 2008

스파게티



오늘은 스파게티를 만들어봤다.

사실 뭐 이건, 재료 볶고 면 삶고 같이 조금 볶고, 소스 붓고 조금 볶고, 치즈 붓고 조금 볶고 ..
끝... -_-?

볶는 거야 누구나 할 수 있는 거고,
면 삶는 거야 대강 씹어보고 결정하면 되고...
결국엔 소스인거야!!! 소스 맛난 걸 쓰고, 데코레이션을 잘하면 되는 거였어!
소스까지 만들라고 하신다면.. 그건 반칙.

브로콜리를 사왔었는데, 깜빡하고 안 넣었다. 푸하핫.
하지만 기타 야채들이 엄청 많았기 때문에 어색하지 않았고,
맛도 첫번째 스파게티 치고는 상당히(!) 괜찮았다.
요리실력이 2g 늘은듯? :)

재료:
양파, 마늘, 빨강피망, 녹색피망, 베이컨, 버섯, 스파게티면, 소스, 모차렐라 치즈, 토마토.

다음번엔 까르보나라 스파게티에 도전.
이미 까르보나라 용 소스도 냉장고에 있음. 퀠퀠.

Saturday, December 20, 2008

Hardys VR Cabernet Sauvignon 2007



Yeah. This is the one of the my holiday's necessaries.
Its amount is 1Liter!!!
Normal wine's amount is 750ml. It's a little bit lack for two guys greedy self.

Its taste is normal. A well matched with meat and other food.
Normal is good. :)

---------------------------------------------

Name : Hardys Cabernet Sauvignon VR 2007
Country : Australia
Vintage : 2007
Style : Dry
Colour : Red
Sweet : 3.5 / 5
Tannin : 3.5 /5 
Deep : 3 / 5
Price : 3.5 / 5 (SGD $19)

Overall : 3.4 / 5

Jacob's Creek Grenache Shiraz Vintage 2007



The right side one.
I got this wine on impluse buying. -0-
They were discounting about 20%!!!
I couldn't help it. So i bought some kinds of jacob's creek wines.

I enjoyed the wine which name is different from usual wines.
Grenache??? I saw first time its name was grenade. huhu.
Anyway, I tasted it. But it was also differenet from usual taste....
It couldn't make me happy. I was just satisfied with it. Not great.

And I think the grape's quality is better 2006 than 2007.
2004 is the best over 2000 years. I think so. This wine is 2007 year wine.
I think that it is an additional reason that it couldn't give me good taste.

------------------------------------------

Name : Jacob's Creek Grenache Shiraz Vintage 2007
Country : Austrailia
Vintage : 2007
Style : Dried Wine. Not a full body.
Colour : Red
Sweet : 3.5 / 5
Tannin : 3 / 5
Deep : 3 / 5
Price : 3 / 5 (SGD$ 19.5)

Overall : 3.2 / 5

테팔, 와인, 요리


그동안 요리를 할 때, 싸구려 솥단지를 이용했었는데, 음식이 맨날 탔다. ㅠㅠ
조금만 방심하면 타버려서 첫날만 맛있고 그 담부턴 탄 음식.
그리고 설겆이 할 때도 애로사항이 꽃이피었다. 
그래서 구입한 테팔 프라이팬 겸 솥단지!!!! 아 이거 작살이다. 푸하하하.
왜 어머니들께서 주방 용품 하나하나에 그런 많은 신경을 쓰시는 줄 알아버렸다.
실제로 좋은걸 사고 나니깐 기분도 좋고 요리도 편하고 맛도 좋고 이거야 말로 일석 삼조!!!

그런데 난 원래 테팔 솥단지만 사려고 갔던건데, Jacobs Creek 이 할인을 하길래 4병이나 구입.
Jacobs Creek Cabernet Sauvignon 2006 x 2
Jacobs Creek Shiraz 2006 x 1
Jacobs Creek Grenache Shiraz 2007 x 1
충동구매 완료!



테팔을 이용한 첫번째 요리... 가 아닌 간식.
스팸짤라서 계란 묻혀서 구웠고, 가운데는 삼겹살이 자리잡고 있다.




이건 오늘 토요일. 장을 보러 IMM 이라는 겁나 큰 쇼핑몰에 가서 질렀다.
다음주 수요일부터 거의 2주동안 휴일이기 때문에, 그 때 먹을 쌀, 고기, 채소등을 구입하면서
와인도 깔끔하게 구입!!! 종류도 다양하다. 칠레, 프랑스, 미쿡, 호주.
하나씩 먹으면서 나름 까다로운 평도 내려주겠어. 퀠퀠.



무적 테팔로 만든 떡볶이.
끓여도 끓여도 타지를 않아! 들러붙지도 않고!!!! 역시 테팔!!!!
아 겁나 맛나게 먹었다. 최고야.


Friday, December 19, 2008

boost::asio - Network Library modified by Terry - 3

boost::asio 내 맘대로 바꾼 버전 3번째.
client 부분임.

client 특징:
- 거의 모든 기능이 session 에 들어가 있기 때문에 초 간단함.
- connect 를 async / blocking 두 가지 모두 지원하지만 blocking 을 추천.
- 기본적으로 ioservice 가 iocp 를 사용하기 때문에, thread 를 돌림.
- 사용하는 쪽에서는 끝날 때까지 loop 돌려주다가 join 호출해서 종료하면 됨.

client.h

#pragma once

#ifndef _ASIO_CLIENT_H_
#define _ASIO_CLIENT_H_

#include "session.h"

class asio_client
{
private:
boost::asio::io_service& io_service_;
tcp::resolver::iterator endpoint_iterator_;
session_ptr session_;
boost::thread t_;

void* cb_class_;
cb_connect cb_connect_;

bool started_;

public:
asio_client(boost::asio::io_service& io_service, tcp::resolver::iterator endpoint_iterator) :
io_service_(io_service), endpoint_iterator_(endpoint_iterator),
cb_class_(0), cb_connect_(0),
started_(0)
{
session_ptr new_session(new session(io_service));
session_ = new_session;

//connect();
}

void connect()
{
tcp::endpoint endpoint = *endpoint_iterator_;
session_->socket().async_connect(endpoint,
boost::bind(&asio_client::handle_connect,
this,
boost::asio::placeholders::error,
++endpoint_iterator_)
);
}

void connect_blocking()
{
boost::system::error_code error;
session_->socket().connect(*endpoint_iterator_, error);

if(error)
{
cerr << "Error! failed to connect to a patch server : << " << started_ =" true;" started_ ="="" t_ =" boost::thread(boost::bind(&boost::asio::io_service::run," started_ ="="" cb_class_ =" cb_class;" cb_connect_ =" f_connect;">set_callback(cb_class, f_parser);
}

protected:
void handle_connect(const boost::system::error_code& error, tcp::resolver::iterator endpoint_iterator)
{
if(error)
{
cerr << "\n -Error- failed to connect to a patch server : << " <<>do_async_read();
}

void do_close()
{
cout << "Close socket" <<>socket().close();
}
};

typedef boost::shared_ptr asio_client_ptr;

#endif//_ASIO_CLIENT_H_

Monday, December 15, 2008

boost::asio - Network Library modified by Terry - 2

boost::asio 내 맘대로 바꾼 버전 2번째.
session 부분임.

session 특징:
- TCP session. Server / Client 모두 다 사용.
- 접속하였을 때와 패킷을 받았을 때 콜백 호출. 나머지 필요하면 그때 새로운 콜백 추가.
- ReadBuffer 를 그냥 packet_parser 콜백에 넘기기 때문에, 더 좋은 성능을 이끌어 내고 싶으면
- packet_parser 콜백 받는 부분에서 버퍼를 복사한 후 다른 쓰레드로 넘겨서 처리해야 함.
- packet_parser 부분이 길어지게 되면 당연히 async_read 를 늦게 걸 수 밖에 없기 때문에 성능이 저하됨.
- 에러처리는 기본적인 것만 되어 있음.

session.h



#pragma once

#ifndef _SESSION_H_
#define _SESSION_H_

#include "structure.h"
#include
#include

using boost::asio::ip::tcp;
using namespace std;

class session;

typedef boost::shared_ptr session_ptr;
typedef boost::function cb_boost_func;

typedef bool (*cb_packet) (void* cb_class, packet_ptr p, session_ptr s);
typedef bool (*cb_connect) (void* cb_class, session_ptr s, const boost::system::error_code& error);

class session : public boost::enable_shared_from_this
{
private:
tcp::socket socket_;
data_buffer read_buffer_;
data_buffer write_buffer_;

bool authorized_;

void* cb_class_;
cb_packet parse_packet_;

public:
session(boost::asio::io_service& io_service) :
socket_(io_service), authorized_(0), cb_class_(0), parse_packet_(0)
{
}
virtual ~session() {;}

tcp::socket& socket() { return socket_; }

bool get_authorized() const { return authorized_; }
void set_authorized(bool value) { authorized_ = value; }

void start()
{
do_async_read();
}

void send_packet(packet_ptr packet)
{
// check a packet size
if(packet->body_length_ > max_body_size)
{
cerr << "\n -Error- packet size is too large : " << packet->body_length_ << "\n";
return;
}

do_async_write(packet);
}

void set_callback(void* cb_class, cb_packet cb_func)
{
cb_class_ = cb_class;
parse_packet_ = cb_func;
}

void do_async_read()
{
// read only header
boost::asio::async_read(socket_,
boost::asio::buffer(read_buffer_.data_.begin(), header_size),
boost::bind(&session::do_async_read_body,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);

//socket_.async_read_some(
// boost::asio::buffer(read_buffer_.data_.begin(), max_packet_size),
// boost::bind(&session::handle_read,
// shared_from_this(),
// boost::asio::placeholders::error,
// boost::asio::placeholders::bytes_transferred)
// );
}

void do_async_read_body(const boost::system::error_code& error, size_t bytes_transferred)
{
if(error)
{
if(bytes_transferred == 0)
cerr << "\n -Close socket. \n";
else
cerr << "\n -Error- do_async_read_body (" << error.message() << ")\n";

// close this socket
this->socket_.close();
return;
}

packet_header header;
memcpy(&header, static_cast(read_buffer_.data_.begin()), header_size);

// read body
boost::asio::async_read(socket_,
boost::asio::buffer(&read_buffer_.data_[header_size], header.body_length_),
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
}

void do_async_write(packet_ptr packet)
{
memcpy((void*)&write_buffer_.data_[0], (void*)static_cast(packet.get()), header_size);
memcpy((void*)&write_buffer_.data_[header_size], (void*)packet->data_, packet->body_length_);

boost::asio::async_write(socket_,
boost::asio::buffer(write_buffer_.data_.begin(), header_size + packet->body_length_),
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
}

protected:
void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
if(error)
{
cerr << "\n -Error- handler_read (" << error.message() << ")\n";
// close this socket ?
return;
}

cout << "\nhandle_read : bytes_transferred " << bytes_transferred << " bytes" << endl;

if(bytes_transferred == 0)
{
// normal close.
return;
}

if(bytes_transferred > max_packet_size)
{
cerr << "\n -Error- handler_read : too many transferred bytes (" << bytes_transferred << ")\n";
return;
}

packet_header* header = reinterpret_cast(read_buffer_.data_.begin());
if(!header || header->body_length_ <= 0 || header->body_length_ > max_body_size)
{
assert(header);
cerr << "\n -Error- handler_read : abnormal error read buffer" << std::endl;
return;
}

packet_ptr packet(new packet);
packet->index_ = header->index_;
packet->body_length_ = header->body_length_;

packet->data_ = new char[packet->body_length_];
memcpy(packet->data_, (void*)&read_buffer_.data_[header_size], packet->body_length_);

// invoke a callback function
if(parse_packet_(cb_class_, packet, shared_from_this()) == false)
{
cerr << "\n -Error- handler_read : packet_parse returned false. socket closed." << std::endl;
socket_.close();
return;
}

// do an asynchronous read again
do_async_read();
}

void handle_write(const boost::system::error_code& error, size_t bytes_transferred)
{
#ifdef _DEBUG
cout << "\nhander_write bytes transferred : " << bytes_transferred << " bytes" << endl;
#endif

// do nothing.
}
};

#endif//_SESSION_H_

Saturday, December 13, 2008

20대 나와 함께 했던 사람들

이제 2주반 후면 30살이다. ;;;;;
이게 은근히 싫은 거 같다. :)
사실 별 거 아니긴 한데 말이야. 쩝.

20대 마지막 시점에서 지금의 내가 있을 수 있게 해준 사람들을 돌아봤다.
정말 고마운 사람들이고, 이자리를 빌어서 다시한번 감사를 전하고 싶다.
사람이 살아가는 데 있어서 사람과의 만남, 인연이 정말 중요하다고 생각한다.
지금까지도 잘 지내왔고 앞으로는 더욱 잘 지냈으면 좋겠다.
30대에서도 새로운 사람, 새로운 인연을 잘 만나서 나를 더욱 발전시킬 수 있으면 좋겠다.

* 본명 or 필명을 직접 적습니다. 혹시라도 공개가 껄끄러우신 분은 알려주세요 :)

대학교 시절
석림형님 : PHP 를 최초로 가르쳐 주신 고마우신 선배님.
세연형님 : Linux 와 SQL. 그리고 본격적으로 프로그래밍을 할 수 있게 해주신 선배님.
쓰봉, 갈치 : C++ 팀을 만들어서 다른 이에게 공개하는 최초의 게임(.. 완성은 못했지만.) 을 같이 만들었던 후배들.

아이소닉 시절
경만옹 : 학교에서 정신 못차리고 있던 나를 게임업계로 본격 다이브 시켜주심.
홍기옹 : 아무것도 모르는 생 초보였던 나를 교육 시켜주고 회사에 적응시켜주신 선배님.
용찬옹 : 아타나시아를 같이 만들면서 많은 지식을 공유했고, 버파의 세계로 이끌어줌.
택트형 : 생각하는 것도 비슷하고, 취미 관심분야도 비슷한 친구같은 형.

NHN 시절
종석형, 광준형 : 나를 뽑아주시고, 아크로드에 모든 것을 쏟을 수 있게 만들어 주심.
진영형 : 힘들었던 시절 정말 많이 도와주신 고마우신 형님.
남영형 : NHN 에 같이 입사해서 정말 힘이 많이 되준 형.
용준형 : 정말로 힘든 시절을 같이 해서 이겨낸 형님.
대환형 : 항상 나를 믿어주고 정신차리게 해주신 형님.
성경형 : 많은 지식을 알려주시고, 새로운 길을 걷게 해주신 결정적 형님.
오휴붕 : 회사에 동갑친구가 거의 없는데, 여러가지 많은 걸 공유하는 친구.

Real U 시즌 중
경환형님 : 새로운 환경에서 일을 할 수 있게 나를 뽑아준 형님.
승주형, 재호형 : 싱가폴 초반에 맨땅에 헤딩하던 나를 많이 도와주신 형님들.

20대 내내.
무식한 3인방 + 매니져 우시경 : 땡큐!!!!!
좍 : 항상 고맙다.


이 외에도 정말 많은 분들께서 저의 20대를 만들어 주셨습니다.
혹시나 위 목록에 없다고 해서 마음 상하지는 말아주시길. 항상 감사드리고 있으니깐요. :)
30대 때도 잘 부탁드립니다요~

칠리크랩, 클라키, 삼겹살

싱가폴에 온지 3개월이 넘도록 싱가폴 대표음식을 못 먹어봐서
지난 금요일에 형들하고 다녀왔다.

대표음식은 칠리크랩. 사실 게요리를 잘 못 먹기 때문에 그렇게 절실하지 않았던 것 같긴하다.



역시나 이번에도 잘 발라먹기 힘든 것 때문에 엄청 투덜대면서 먹었다.
글치만 소스는 아주 맛있었다.



같이 간 형님 두 분.



클라키 안에 있는 병원놀이 맥주집에서 한 컷.



중간에 빵판 같은 거에다가 작은 발광다이오드를 꽂으면 불이 들어오는 녀석이 있었다.
거기에 내 이름 만들고 한 컷.


조금 전에 먹은 저녁.
오늘 토요일 쉬면서 러닝, 웨이트 트레이닝, 수영 까지 마친 후 단백질 보충 :)
브라질 냉동 삼겹살인데, 맛은 약간 떨어지지만 가격이 워낙 저렴해서 먹어주고 있다.
옆에 있는 녀석은 카레. 세 번째 카레 요리인데, 이번이 제일 잘 됬다. 이제 카레는 마스터.
풀도 많이 먹으면서 밸런스 유지. 후후후.

Wednesday, December 10, 2008

The Dark Knight



The Dark Knight
Score : ★★★★★

Incredible!!!! It's really drop dead gorgeous.
It ranks a full score of my private movie grade.

When I was in Singapore just 2 weeks, I watched this movie in the theater.
But I couldn't understand its story over 80%. 
The batman's speech is really in a husky voice. It makes me more difficult to understand.
Also my english skill was extremely poor. :)

At last, its dvd has been released.
I got it, and watched with Korean subtitles.
Wow~ Excellent!!! What a Fantastic movie!!

More, I'm watching it again with English subtitles now.
GoGoGo~

+ My top score movies.
The Terminator 2
The Usual Suspects
The Matrix
The Dark Knight

To do

Request addresses of mother's company and father's company from sister.

Monday, December 8, 2008

Nottage Hill Cabernet Shiraz 2007



I considered which wine is proper with korean-spicy-rice-cake.
But, I didn't think about over S$30. just below it. And new wine.

I chose two wines, and hesitated for a while.
One wine was a red label merlot, the other one was this.
Eventually, I chose a cheaper one. hahaha.

I made a mistake manage the temperature for this wine.
Even though the mistake, its taste was nevertheless fine.

I recognize once again, a wine's taste is not depend on its price.
That's it!

---------------------------------------------------

Name : Hardys Nottage Hill Cabernet Shiraz 2007
Country : Austrailia
Vintage : 2007
Style : Full bodied dry
Colour : Red
Sweet : 3.2 / 5
Tannin : 3.1 / 5
Deep : 3.4 / 5
Price : 3.8 / 5 (S$22+)

Overall : 3.4 / 5

떡볶이




부대찌개, 카레 에 이은 세번째 요리.
요리라고 하기엔 너무나도 쉬운 -_-....... 떡볶이 임.

싱가폴 오는 날 부터 지금까지 너무너무 먹고 싶었기 때문에,
재료가 얼마를 하던 간에 마구마구 구입해서 해  먹었다. 

떡볶이 떡 : 1만원
고추장 : 집에서 날아온 놈.
올리브 유 : 5천원
마늘 : 800원. (4개)
양파 : 1200원. (4개)
파 : 600 원 (대파 1개)
오뎅 : 2천원 (엄청 많음)
다진 소고기 : 3천원 (꽤 양이 됨.)
라면 : 있던 거.
설탕 1kg : 3천원.

음.. 다 합쳐보니 떡볶이 떡 말고는 굉장히 싸다.
떡볶이 떡은 그 어디에서도 팔지를 않아서 한국 마트에서 구입. 그래서 비쌌음.. ㅠㅠ
싱가폴은 말레이시아와 인도네시아, 호주 등지에서 기본 곡물을 매우 싼값에 수입해 오기 때문에
기본 곡물 및 채소 과일 가격들은 상당히 저렴한 편.

적당한 크기의 프라이팬이 없어서 야채만 볶은 후 솥단지로 이적.
기대이상으로 너무 맛있어서 정말 좋았다.
순대까지 같이 있었다면 정말 최고였을텐데 말이지.

요리 실력이 1g 늘었음.
앞으로 스파게티, 피자 등에 도전한 후에 다양한 요리를 해봐야겠다.
싱가폴에 있는 동안 요리를 마스터 해야지 :)

Sunday, December 7, 2008

경사

우리 집안의 자랑인 작은아버지네 가족.

첫째 아들은 이번에 레지던트를 마치고 본격 의사로 돌입.

둘째 아들은 이번에 사법고시 한방에 합격.

어제 한국에서는 가족들 전부가 모여서 파티를 했다고 함.

최근 몇 년동안에는 친가들이 사이가 많이 좋아져서

서로 축하해주고 기뻐하는 모습이 참 보기 좋다.



참 기분좋고 기뻐할 일이긴 한데, 이렇게 되다 보니 더욱 높은 곳에 올라가야 겠다는 마음뿐...

음... 블리자드가서 성공적인 게임을 만들면, 저 정도급으로 인정받을라나? :)

택진이 아저씨나 범수아저씨처럼 대박을 내야 될 수 있으려나.



암튼 작은 아버지, 작은 어머니 진심으로 축하드립니다~


Friday, December 5, 2008

boost::asio - Network Library modified by Terry - 1

boost::asio 를 분석한 후 사용방법이라던지,
코드의 확장이 제대로 된 예제가 전혀 없어서,
내 입맛에 맞게끔 수정을 가해서 쓰고 있다.
매우 간단하지만, 상당히 잘 동작하는 편이여서 마음에 든다.

소스가 다 나열하기에는 조금 길어서 5~6 번 정도에 나누어서 올릴 계획.
첫번째는 기본이 되는 packet structure 정의.

주요 특징:
- boost::asio network library 에서 사용하기 불편한 점을 보완.
- 각 socket 마다 꽤나 큰 read / write buffer 를 들고 있음.
- buffer 구조가 매우 단순하므로 mmo 에 당장 사용하기에는 무리가 있음.
- 현재 잘 동작하고 있지만, buffer 에 문제가 생기면 allocator 를 도입할 에정.
- client 연결이 많고 mmo 처럼 패킷 받은 후에 처리해야할 양이 많은 경우, packet parse 용 thread 를 따로 만들어서 동작시키는 것이 당연함!

- callback 을 boost::function 을 사용해서 좀 세련되게 하고 싶었으나, object 를 넘기는 과정에서 계속 complie error 가 발생.
- 시간관계상 그냥 C style callback 유지. 귀찮아서 다시 function 작업은 안해봤음. :)

structure.h


#include
#include
#include
#include

struct packet_header
{
unsigned short index_;
unsigned short body_length_;

packet_header() : index_(0), body_length_(0) {}
};

struct packet : public packet_header
{
char* data_;

packet() : data_(0) {}
~packet() { if(data_) delete [] data_; }
};

const int header_size = (int)sizeof(packet_header);
const int max_body_size = 1024; // If you need more size, just edit this!!!
const int max_packet_size = header_size + max_body_size;

struct data_buffer
{
boost::array data_;
};

typedef boost::shared_ptr packet_header_ptr;
typedef boost::shared_ptr packet_ptr;
typedef boost::shared_ptr data_buffer_ptr;

C# Client Network Library

C# 하면서 만들었던 거의 기억보존용.

아직 테스트 중이고, 살펴보면 허술한 부분도 많지만
뭐 간단하게 동작하는 데는 큰 문제 없음.

주요 특징 :
- Async 를 걸고 IOCP 에서 return 받는 간단한 구조.
- 방식은 proactor 이지만 thread 가 하나이기 때문에 뭐라 지칭하긴 그렇고, 그냥 비동기 콜임. :)
- boost::asio 를 많이 모방했음. 그래서 함수 이름이나, packet 을 읽는 방식이 거의 같음. -0-;
- connect 는 sync, send/recv 는 async.

Packet type - namespace Protocol

namespace Protocol
{
public struct packet_header
{
public System.UInt16 index_;
public System.UInt16 body_length_;
}

public struct packet
{
public packet_header h_;
public System.Byte[] data_;
}

public class packet_size
{
public static readonly int header_size;
public static readonly int max_body_size;
public static readonly int max_packet_size;

static packet_size()
{
header_size = Marshal.SizeOf(typeof(packet_header));
max_body_size = 1024;
max_packet_size = header_size + max_body_size;
}
}
}


Network Library - namespace NetworkLib

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

using Protocol;

namespace network_lib
{
public class packet_args : EventArgs
{
private packet p_;
public packet_args(packet p)
{
p_ = p;
}

public packet data
{
get { return p_; }
}
}
public delegate void packet_event(object sender, packet_args p);

class packet_parse
{
public event packet_event e_;
public void do_packet_parse(packet p)
{
if (e_ != null)
e_(this, new packet_args(p));
}
}

public class client_session
{
#region Private Variables

private string ip_;
private string port_;
private Socket client_socket_;

private packet read_packet_;
private Byte[] read_buffer_;
private Byte[] write_buffer_;

private IAsyncResult result_;
private AsyncCallback cb_async_read_body_;
private AsyncCallback cb_handle_read_;
private AsyncCallback cb_handle_write_;

private packet_parse event_packet_;

#endregion

#region Constructors

public client_session()
{
init();
}

public client_session(string ip, string port)
{
ip_ = ip;
port_ = port;

init();
}

#endregion

#region Properties

public string IP
{
get { return ip_; }
set { ip_ = value; }
}

public string Port
{
get { return port_; }
set { port_ = value; }
}

public bool connected
{
get { return (client_socket_ != null) ? client_socket_.Connected: false; }
}

#endregion

#region Public Methods

public void add_packet_event(packet_event h)
{
event_packet_.e_ += h;
}

public void connect()
{
try
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(ip_), System.Convert.ToUInt16(port_));
client_socket_ = new Socket(System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp);
client_socket_.Connect(ip);
if (client_socket_.Connected)
do_async_read();
}
catch (SystemException se)
{
MessageBox.Show(se.Message);
}
}

public void disconnect()
{
if (connected)
client_socket_.Disconnect(false);
}

public void do_async_read()
{
try
{
// do_async_read_head
result_ = client_socket_.BeginReceive(read_buffer_,
0,
packet_size.header_size,
SocketFlags.None,
cb_async_read_body_,
read_buffer_);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}

public void do_async_write(packet p)
{
try
{
packet_header heaer = p.h_;
System.Byte[] buffer = raw_serialize_ex(heaer);
buffer.CopyTo(write_buffer_, 0);
p.data_.CopyTo(write_buffer_, packet_size.header_size);

// do_async_write
result_ = client_socket_.BeginSend(write_buffer_,
0,
packet_size.header_size + p.h_.body_length_,
SocketFlags.None,
cb_handle_write_,
write_buffer_);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}

// copied from group.google.com
public object raw_deserialize_ex(byte[] rawdatas, Type anytype)
{
int rawsize = Marshal.SizeOf(anytype);
if (rawsize > rawdatas.Length)
return null;
GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
IntPtr buffer = handle.AddrOfPinnedObject();
object retobj = Marshal.PtrToStructure(buffer, anytype);
handle.Free();
return retobj;
}

// copied from group.google.com
public byte[] raw_serialize_ex(object anything)
{
int rawsize = Marshal.SizeOf(anything);
byte[] rawdatas = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
IntPtr buffer = handle.AddrOfPinnedObject();
Marshal.StructureToPtr(anything, buffer, false);
handle.Free();
return rawdatas;
}

#endregion

#region Private Methods

private void init()
{
client_socket_ = null;

cb_async_read_body_ = new AsyncCallback(do_async_read_body);
cb_handle_read_ = new AsyncCallback(cb_handle_read);
cb_handle_write_ = new AsyncCallback(cb_handle_write);

read_packet_.data_ = new System.Byte[packet_size.max_body_size];
read_buffer_ = new System.Byte[packet_size.max_packet_size];
write_buffer_ = new System.Byte[packet_size.max_packet_size];

event_packet_ = new packet_parse();
}

private void do_async_read_body(IAsyncResult r)
{
try
{
int bytes_transferred = client_socket_.EndReceive(r);
if (bytes_transferred == 0)
{
// normal close
return;
}

if (bytes_transferred != packet_size.header_size)
{
MessageBox.Show(" !Error - invalid received header size : " + bytes_transferred);
return;
}

packet_header header;
System.Byte[] header_buffer = new System.Byte[packet_size.header_size];
System.Buffer.BlockCopy(read_buffer_, 0, header_buffer, 0, packet_size.header_size);
header = (packet_header)raw_deserialize_ex(header_buffer, typeof(packet_header));

read_packet_.h_.index_ = header.index_;
read_packet_.h_.body_length_ = header.body_length_;

// do_async_read_body
result_ = client_socket_.BeginReceive(read_buffer_,
packet_size.header_size,
header.body_length_,
SocketFlags.None,
cb_handle_read_,
read_buffer_);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}

private void cb_handle_read(IAsyncResult r)
{
try
{
int bytes_transferred = client_socket_.EndReceive(r);
if (bytes_transferred > packet_size.max_body_size)
{
MessageBox.Show(" !Error - invalid received body size : " + bytes_transferred);
return;
}

System.Buffer.BlockCopy(read_buffer_, packet_size.header_size, read_packet_.data_, 0, bytes_transferred);

// parse packet
event_packet_.do_packet_parse(read_packet_);

// do_async_read
do_async_read();
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}

private void cb_handle_write(IAsyncResult r)
{
int bytes_transferred = client_socket_.EndSend(r);
string msg = "packet has been sent. bytes : " + bytes_transferred + "\n";
}

#endregion
}
}

책 구입

아마존에서 책 3권을 샀는데,

배송비 포함해서 무려 US$115.63 !!!!

현재 환율로 계산하면

115.63 * 1,475.50 = 163,905.525 원

아. 겁나 비싸다. -_-;;;

결국에 한국 환율로 계산해서 통장에서 빠져나가는데...

싱가폴에서 신용카드를 하나 만들긴 해야겠다.

그래야 조금이라도 아낄 수 있을 듯.

Wednesday, December 3, 2008

Monday, December 1, 2008

The end of the probation

3개월의 Probation 이 끝났다.

처음에 올 때는 정말 걱정 많이 했었다.

영어가 제일 컸고, 적응을 잘할 수 있을까 걱정했었는데...

어떻게 잘 된 거 같다. 역시 닥치면 다 하는 건가 :)

이제 남은 한달 잘 마무리 하면서

다가오는 30살을 준비해야겠다. -_-

To do

Make a payment to owner.