java.nio.channels.Selector 사용법 정리


한개의 Process에서 여러개의 Socket을 다루는 방법은 크게 두가지가 있다. 


  1. Thread 

  2. IO Multiplexing


내가 10년 전에 C/C++로 네트웍 프로그래밍을 땐 간단했었다. select() (참고 : http://man7.org/linux/man-pages/man2/select_tut.2.html ) 함수 하나만 제대로 알면 모든 것을 정복할 수 있었다. 게다가 Blocking Socket 으로 Multiplexing을 구현할 수도 있었다. C/C++에선 간결한 API를 통해 너무 쉽게 적용할 수 있었다. 


최근 Java로 네트웍 프로그래밍 할 일이 있었는데, 처음 접한 네트웍 프로그래밍이라 그런지 복잡하게 느껴졌다. C의 select() 를 대신할 Selector부터 쉬운 접근은 아니었다


다음을 차근 차근 따라해보면 답이 보이겠지만 처음이라면 쉬운 접근은 아닌 듯 하다. 


  1. selector = Selector.open()

  2. server = ServerSocketChannel.open(); // Server Socket 을 여는 경우

      server.socket().bind(new InetSocketAddress( PORT ));

       server.configureBlocking(false);

       server.register(selector, SelectionKey.OP_ACCEPT);

      

      SocketChannel ( ServerSocketChannel )객체에서 register(selector, Options) 해야 함. 

      4가지 옵션이 있음. SelectionKey.OP_ACCEPT, OP_READ, OP_WRITE, OP_CONNECT

      단독으로 쓰거나 중복 가능. 중복은 ( SelectionKey.OP_READ | SelectionKey.OP_WRITE )

      register() 전에 configureBlocking(false) 해서 non-blocking 모드로 설정해야 함.


  3. selector.select() 를 통해 옵션에 따른 대기 중인 SocketChannel을 알아내기.


  4. 각 상황에 맞는 처리.

       Iterator<SelectionKey> iter = selector.selectedKeys().iterator();

       while(iter.hasNext())

       {

             SelectionKey key = iter.next();

             if( key.isAcceptable() )

             {

ServerSocketChannel serversocket = (ServerSocketChannel) key.channel();

SocketChannel client = serversocket.accept();

             }

             else if( key.isReadAble() )

             {

                 SocketChannel socket = (SocketChannel) key.channel();

             }

             else if( key.isWriteAble() )

             {

                 SocketChannel socket = (SocketChannel) key.channel();

             }

       }


  0. 끊거나 끊겼을 경우

key.cancel();

key.channel.close();

      보통 Socket이 끊겼는지 여부는 read()을 호출하였을 때 return value가 -1이면 끊긴 것이다.



내가 평소에 사용하는 방법


Selector selector = null;

ServerSocketChannel server = null;

selector = Selector.open();

server = ServerSocketChannel.open();


server.socket().bind(new InetSocketAddress( PORT ));

server.configureBlocking(false);

server.register(selector, SelectionKey.OP_ACCEPT);


while(true)

{

int rv = selector.select(300);

if (rv == 0)

continue

Iterator<SelectionKey> iter = selector.selectedKeys().iterator();

while(iter.hasNext())

{

  SelectionKey key = iter.next();

if ( key.isAcceptable() )

{


SocketChannel client = key.channel().accept();


if (client != null)

{

client.configureBlocking(false);

client.register(selector, SelectionKey.OP_READ); // 수신만 원하는 경우

}

}

if ( key.isReadable() )

{

   SocketChannel socket = (SocketChannel) key.channel();

}

else if( key.isWriteable() )

{

               SocketChannel socket = (SocketChannel) key.channel();

}

}

}


Posted by Picky Kang
,

아마추어 아이스하키 팀 정리했습니다. 주로 토,일요일과 평일 밤에 팀이 많습니다. 잘못된 정보 있으면 알려주시고, 새로 생긴 팀이 있다면 알려주세요. 


잘 안보이시면 다음링크 타고가서 보세요. 

아마추어아이스하키팀 리스트 : http://goo.gl/OEZ685



Posted by Picky Kang
,

USD로 결제할 수 있는 하나 글로벌페이체크카드를 만들었다. 호텔 예약할 때 보증금으로 사용하고, 취소 했을 때 USD로 환불받기 위함이다.


보통 신용카드 해외결제 수수료는 AMEX 1.4%, VISA 1.0%, MASTER 1.0%, 또 국내 카드사가 0.18%~0.35% 추가 부과한다. 하지만 이 카드는 이런 수수료가 없다.


하나 글로벌페이카드는 외화통장과 연결된다.


하나은행에 신분증만 들고가면 쉽게 만들 수 있다. 

원화 통장 1개, 외화 통장 1개, 체크카드 1개 만들어 준다. 3개가 한 세트.


원화 통장에 입금하면 환전하기 위해 바로 출금 처리 된다. 출금된 돈은 환전 후 바로 외화 통장으로 입금된다.

환율도 괜찮다. 11월 10일 두번 입금했는데, 오후 2시 30분 환율은 모르겠고, 영업시간 끝나고 입금한 것은 송금기준환율(1085.20, 전신환매도율이라고 함)으로 적용되었다.  87995/1095.7 = 80.30939 => 80.31. 현금은 1.75% 은행에서 수수료로 떼는데 송금기준환율은 약 1%정도 되는 것 같다. 40%정도 환율 우대. 물론 은행가서 현금으로 바꾸면 50~80%우대는 쉽게 받는다.


이날 모두 2건의 Las Vegas 호텔을 예약했다. 1개는 USD 80.64(세금포함), 나머지 한개는 USD 69.99(세금 불포함). 처음 결제 건은 5성급 호텔인데 라스베가스+평일이라 무지 싸다.

USD 80.64는 호텔 사이트에서 예약해서 바로 결제 처리 되었고,

USD 69.99(세금포함하면 78.39)는 booking.com통해 예약한 것인데 호텔에서 결제 처리하면서 금액을 잘못 입력했는지 한번 더 결제했다. (70.39 + 8.00)

<호텔 사이트에서 직접 예약 후 받은 Confirmation>

호텔 사이트에서 예약한 내역

<booking.com 에서 예약 후 받은 Confirmation>


이 카드의 장점은 수수료 부담이 없고, 환전 시기를 내가 조절할 수 있다. 환전하고 싶을 때 입금하면 된다. 신용카드는 매입되는 날의 환율이 적용되어 언제 환전될 지 모르는 단점이 있다.

단점은 국내 사용이 안되고, USD 이외 거래는 1.4%수수료가 추가 된다.

'해외결제' 카테고리의 다른 글

Amazon Currency Converter 의 숨겨진 수수료  (0) 2016.09.09
독일 직구 후기  (0) 2015.03.21
하나 글로벌페이 체크카드 환불 후기  (0) 2014.11.21
Posted by Picky Kang
,