네트워크 프로그래밍 - Nonblocking I/O

chance·2020년 6월 8일
0

Data Conversion

  • 모든 데이터가 byte sequence로 저장
    • 어떤 primitive data type이든 byte로 쓸 수 있음
    • 자바에서 char는 2 byte를 차지한다.
  • Methods
    getChar: 다음 2바이트를 읽고 캐릭터를 만든다.
    putChar: 다음 2바이트에 캐릭터를 쓴다.

Clear vs. Flip

clear: 버퍼를 지우는건 아니지만 의미상 지우고 새로 쓴다.
flip: write 상태에서 버퍼를 읽으려고 준비하는 것

예제

public static void main(String[] args) {
		// TODO Auto-generated method stub
		ByteBuffer buf = ByteBuffer.allocate(16);
		int i=0;
		while (buf.hasRemaining()) {
			buf.put((byte)i);
			i++;
		}
		buf.flip(); //limit -> position, position -> 0 => 읽을 준비
		
		System.out.println(buf);
		showBuffer(buf, "int");
		showBuffer(buf, "char");
		showBuffer(buf, "float");
		showBuffer(buf, "long");		
	}
	
public static void showBuffer(ByteBuffer buf, String type) {
    if(type.equals("int")) {
        while(buf.hasRemaining()) {
            System.out.println(buf.getInt());			
        }
        buf.flip();
    }
    else if(type.equals("char")) {
        while(buf.hasRemaining()) {
            System.out.println(buf.getChar());			
        }
        buf.flip();
    }
    else if(type.equals("float")) {
        while(buf.hasRemaining()) {
            System.out.println(buf.getFloat());			
        }
        buf.flip();
    }
    else if(type.equals("long")) {
        while(buf.hasRemaining()) {
            System.out.println(buf.getLong());			
        }
        buf.flip();
    }
}
  • int의 경우 한 데이터 당 4byte를 차지하므로 쓸 때는 byte로 바꾼 16개의 숫자를 쓰고 읽을 때 4개의 숫자를 읽는다.

  • char의 경우 한 데이터 당 2byte를 차지하므로 쓸 때는 byte로 바꾼 16개의 숫자를 쓰고 읽을 때 8개의 숫자를 읽는다.

  • float, long도 마찬가지이다.

  • int로 읽고 쓸 때 첫번째 숫자는 다음과 같이 만들어졌다.

    1. 각각의 바이트에 0,1,2,3이 저장된다.
    2. 읽을 때 한 숫자로 읽어서
00000000 - 00000001 - 00000010 - 00000011
= 2^16 + 2 * 2^8 + 3
= 65536 + 512 + 3 = 66051

View Buffers

  • buffer를 생성하면 backing array가 생성된다.
  • accessor라고 생각하면 편하다.
  • bytebuffer로 타입을 정해서 가져와도 되지만, accessor를 정해진 타입으로 만들 수 있다.
    (e.g. IntBuffer, ShortBuffer, ByteBuffer, CharBuffer, ...)
  • 버퍼의 limit, capacity, mark, position은 따로 있다.
  • view buffer의 변화는 underlying buffer에 반영이 된다. 역도 성립
ByteBuffer buffer = ByteBuffer.allocate(4);
IntBuffer view = buffer.asIntBuffer();

Compacting buffers

  • 채널로부터 읽어들여서 버퍼에 써야하는데 버퍼에서 읽어야되는 데이터가 남아있다면?
  • clear()를 써줄 때 남아있는 데이터가 읽히지 못하고 손실된다.
  • 해결책: compact()를 사용하면 남아있는 데이터를 맨 앞으로 배치하고 그 뒤에 position을 놓는다. 따라서 데이터의 손실이 없다.

Duplicating buffer

  • 같은 array 하나를 duplicate
  • 하나의 copy가 바뀌면 모두 바뀐다.
  • position, mark, limit, capaicty 모두 따라감
  • client가 연결될 때마다 프로그램은 buffer의 duplicate을 만든다.
  • duplicate이 없다면 한 client는 다른 클라이언트가 끝날 때까지 기다려야할 것
  • 버퍼를 동시에 사용하게 해준다.

Read-only Copy

  • position과 limit 사이에 해당하는 버퍼만큼 가져와서 copy한다. 독립적인 property를 갖는 버퍼가 생성된다.
profile
프론트엔드와 알고리즘을 주로 다룹니다.

0개의 댓글