▶ List 인터페이스

 

리스트(List)는 순서를 가지는 원소들의 모임으로 중복된 원소를 가질 수 있다.

 

위치(index)를 사용하여 원소에 접근한다는 점이 배열과 동일하다.

 

리스트에 들어 있는 원소들의 인덱스는 0부터 시작한다.

 

리스트 인터페이스는 ArrayList, LinkedList, Vector 등의 클래스에 의하여 구현된다Vector 클래스는 이전 버전에서도 있었던 것으로 멀티 스레드 환경에서도 사용할 수 있도록 동기화되어 있다.





▶ ArrayList


- 저장되는 데이터의 개수에 따라 자동적으로 크기가 변경된다.

- 가변 크기의 배열(Dynamic Array)이라고도 불린다.

- 원소가 삭제되면 그만큼 크기를 줄이게 된다.

- 타입 매개변수를 가지는 제네릭 클래스로 제공된다.


ArrayList<String> arrList = new ArrayList<String>(); //타입 매개변수 지정

 

[기본 연산]

  • 데이터 저장 시 Collection 인터페이스의 add() 메소드를 사용한다.

arrList .add(“Hello”); // index0 : Hello

arrList .add(“World”); // index1 : World

arrList .add(“Good!”); // index2 : Good!


  • 기존의 데이터가 들어 있는 위치를 지정하여 add()를 호출하면그 위치에 삽입된다.

arrList .add(1, “Yeah~”); // index0 : Hello, index1 : Yeah~, index2 : World, index 3: Good!

 

  • 특정한 위치에 있는 원소를 바꾸려면 set() 메소드를 사용

arrList .set(2, “Nice”); // index0 : Hello, index1 : Yeah~, index2 : Nice, index 3: Good!

 

  • 데이터를 삭제하려면 remove() 메소드 사용

arrList .remove(3); // index0 : Hello, index1 : Yeah~, index2 : Nice

 

  • 저장된 객체 가져오려면 get() 메소드 사용

String s = arrList .get(1); // “Yeah~” 반환

 

  • 현재 저장된 원소의 개수를 얻으려면 size() 메소드 사용 (범위를 벗어나는 인덱스를 사용하면 예외가 발생한다.)

 System.out.println("총 원소 개수 : " + arrList.size()); // 출력 결과 → 총 원소 개수 : 3



[추가 연산]

  • 특정 데이터의 위치를 알려면 indexOf() 메소드 사용

int index = arrList.indexOf(“Yeah~”); // 1이 반환된다.


 단중복된 데이터는 맨 처음에 있는 데이터의 위치가 반환된다.


ArrayList<String> arrList2 = new ArrayList<>();

arrList2 .add(“Hello”); // index0 : Hello

arrList2 .add(“Hello”); // index1 : Hello

arrList2 .add(“Good!”); // index2 : Good!


System.out.println(arrList2.indexOf("Hello"); // 0이 반환된다.

  • 탐색을 반대방향으로 하려면 lastIndexOf() 메소드를 사용 (끝에서부터 탐색한다.)

ArrayList<String> arrList2 = new ArrayList<>();

arrList2 .add(“Hello”); // index0 : Hello

arrList2 .add(“Hello”); // index1 : Hello

arrList2 .add(“Good!”); // index2 : Good!


System.out.println(arrList2.lastIndexOf("Hello"); // 1이 반환된다.


- 참고 배열, ArrayList, 문자열 객체의 크기를 알아내는 방법은 서로 다르다.

  • 배열 : array.length

  • ArrayList : arrayList.size()

  • 문자열 : string.length()

- ArrayList에 있는 원소에 접근하는 또 다른 방법은 반복자(iterator)를 사용하는 것이다반복자는 특별한 타입의 객체로 컬렉션의 원소들을 접근하는 것이 목적이다또한 모든 컬렉션에서 반복자를 적용할 수 있다반복자는 java.util 패키지에 정의되어 있는 Iterator 인터페이스를 구현하는 객체이다아래는 Iterator 인터페이스에서 제공하는 메소드이다원래 3개의 메소드만 제공한다.


메소드 

 설명

 hasNext()

 아직 방문하지 않은 원소가 있으면 true를 반환

 next()

 다음 원소를 반환

 remove()

 최근에 반환된 원소를 삭제한다.


- 반복자를 사용하려면 아래와 같이 iterator() 메소드를 호출하여 반복자 객체를 얻어야한다.

 

Iterator iterator = arrList.iterator(); //반복자 객체 얻기

...

while(iterator.hasNext()) {

s = (String) s.next(); //반복자는 Object 타입을 반환하므로 캐스팅해야 한다.

System.out.println(s);

}

 

출력 결과 :

Hello

Yeah~

Nice


- 반복자 사용을 보다 간편하게 한 것은 자바 버전 1.5부터 도입된 for-each 루프이다.





 LinkedList


연결 리스트(LinkedList)는 각 원소를 링크로 연결한다. 따라서 각 원소들은 이전 원소를 가리키는 링크와 다음 원소를 가리키는 링크를 저장한다. 이처럼 자바에서는 모든 연결 리스트가 이중 연결 리스트로 구현되어 있다.


- 중간에 빈번하게 원소(데이터)의 삽입과 삭제가 이루어지는 경우 연결 리스트는 링크만 수정하면 되기 때문에 ArrayList보다 더 효율적이다LinkedList는 위와 같은 연산에서는 일정한 시간이 걸리나 ArrayList에서는 원소의 개수에 비례하는 시간이 소요된다.


- 단, 위치(index)를 가지고 원소를 접근하는 연산은 ArrayList보다 시간이 더 많이 걸린다위치(인덱스) 기반의 접근이 많다면 ArrayList가 더 낫다사용 방법은 ArrayList와 유사하다.


- LinkedList 예제

import java.util.*;
 
public class LinkedListTest {
	public static void main(String[] args) {
		LinkedList<String> linkedList = new LinkedList<String>();
		 
		linkedList.add(“Hello”);
		linkedList.add(“Nice”);
		linkedList.add(“Yeah!!”);
		linkedList.add(“Cheer”);
		linkedList.add(“Up!!”);
		 
		for(int i = 0; i <linkedList.size(); i++) {
			System.out.println(linkedList.get(i));
		}
	}
}


- 연결 리스트도 반복자를 지원한다. 연결 리스트도 리스트이기 때문에 리스트에서 사용하기 편리한 반복자가 제공되는데바로 ListIterator이다.

 

interface ListIterator<E> extends Iterator<E> { 

...

//두 개의 메소드가 제공되며리스트를 역순으로 방문하는 경우에 사용된다.

E previous();

boolean hasPrevious();

...

}


 

배열을 리스트로 변경하는 방법은 Arrays.asList() 메소드를 사용하는 것이다.

  • 이 메소드는 배열을 받아서 리스트 형태로 반환한다.

  • 리스트를 변경하면 배열도 변경되며 그 역도 성립한다.

  • 리스트의 크기는 배열과 같고 변경이 불가능하다.

  • 배열을 컬렉션이나 리스트를 받는 메소드에 매개변수로 넘기는 것을 허용한다.

  • 고정된 크기의 리스트를 원하는 경우에 어떤 일반적인 리스트 구현보다 효율적이다.

List<String> list = Arrays.asList(new String[100]);

 




▶ Vector 클래스

 

Vector 클래스는 java.util 패키지에 있는 컬렉션의 일종으로 가변 크기의 배열(dynamic array)”을 구현하고 있다.

 

배열의 원소 개수가 늘어나면 자동으로 배열의 크기가 늘어난다.

 

- 어떤 타입의 객체라도 저장할 수 있다기초 자료형 역시 오토박싱 기능을 이용하여 객체로 변환되어 저장된다.

 

제네릭도 지원하므로 생성 시 new String<T>의 형태로 선언하면 타입의 객체만을 저장하는 Vector를 생성할 수 있다.

 

자주 사용되는 메소드

 boolean add()

 Vector 객체에 요소를 추가한다.

 boolean add(int index, Object object)

 정해진 위치에 요소를 추가한다.

 Object get(int index)

 해당 위치의 요소를 추출한다추출 시 캐스팅해야 한다.

 int size()

 현재 요소들의 개수를 반환한다.




 

 

 

- Vector 예제

import java.util.Vector;

public class VectorTest {
    public static void main(String[] args) {
        Vector v = new Vector();
        v.add("안녕하세요");
        v.add(new Integer(20));
        v.add(400);

        System.out.println("vector size : " + v.size());

        for (int i = 0; i < v.size(); i++) {
            System.out.println("vector element " + i + " : " + v.get(i));
        }

        String s = (String) v.get(0); //추출 시 형변환 필수 !

    }
}

[출력 결과]

 




 

컬렉션

 

- 컬렉션(Collection) : 자바에서 자료 구조를 구현한 클래스들을 칭하는 용어이다.

 

자료 구조(Data Structure) : 자료를 저장하기 위한 구조이다.

 

대부분의 프로그램은 자료를 저장하여야 하고 따라서 어떤 자료 구조를 사용할 것인지 결정하여야 한다.


많이 사용되는 자료 구조로는 리스트(list), 스택(stack), (queue), 집합(set), 해쉬 테이블(hash table) 등이 있다.

 

 



컬렉션의 종류

 

자바는 컬렉션 인터페이스 컬렉션 클래스로 나누어서 제공한다.

 

컬렉션 인터페이스를 구현한 클래스도 함께 제공하므로 간단히 사용하거나 각각 필요에 맞추어 인터페이스를 자신의 클래스로 구현할 수도 있다.

 

컬렉션 인터페이스와 컬렉션 클래스는 모두 java.util 패키지에 포함되어 있다.

 

컬렉션 라이브러리들은 모두 제네릭 기능을 지원한다.

 

아래는 컬렉션 인터페이스를 간단히 설명한 것이다.


 인터페이스

 설명

 Collection 

 모든 자료 구조의 부모 인터페이스로서 객체의 모임을 나타낸다.

 Set 

 집합을 나타내는 자료 구조로중복된 원소를 가지지 않는다.

 List 

 순서가 있는 자료 구조로중복된 원소를 가질 수 있다.

 Map 

 키와 값들이 연관되어 있는 사전과 같은 자료 구조이다.

 Queue 

 FIFO(First-In-First-Out) 식으로 들어온 순서대로 내보내는 자료 구조이다.

 

자바 버전 1.2이전에는 Vector, Stack, HashTable, Bitset, Enumberation 클래스만 제공하였다.

 

자바 버전 1.2이후에는 위의 기재한 클래스 외에 다양한 클래스를 제공되며, 인터페이스와 구현을 분리하였다.

 

 



▶ Collection 인터페이스


[인터페이스의 계층 구조]


모든 컬렉션 인터페이스의 부모 인터페이스에 해당된다.

 

모든 컬렉션 클래스들이 Collection 인터페이스를 구현하고 있으므로 Collection에 들어 있는 메소드들은 거의 대부분 컬렉션 클래스에서 사용할 수 있다.


- Collection 인터페이스가 제공하는 메소드


기본연산

 int size()

 원소의 개수 반환

 boolean isEmpty()

 비어있으면 true를 반환

 boolean contains(Object obj) 

 해당 객체를 포함하고 있으면 true를 반환

 boolean add(E element)

 원소 추가

 boolean remove(Object obj)

 원소(객체삭제

 Iterator<E> iterator() 

 원소를 순서대로 방문한다.

 벌크연산

 boolean addAll(Collection<? extends E> c)

 c에 있는 모든 원소 추가

 boolean containsAll(Collection<?> c)

 c에 있는 모든 원소가 포함되어 있으면 true

 boolean removeAll(Collection<?> c)

 c에 있는 모든 원소 삭제

 void clear() 모든 원소 삭제

 배열연산

 Object[] toArray()

 컬렉션을 Object 타입의 배열로 변환

 <T> T[] toArray(T[] a) 컬렉션을 해당 입의 배열로 변환





 

제네릭 프로그래밍

 

제네릭 프로그래밍(Generic Programming) : 작성한 코드를 다양한 타입의 객체에 대해 재사용하는 객체 지향 기법이다.

 

제네릭은 자바 버전 1.5부터 추가된 기능으로, 복잡한 애플리케이션을 개발할 때 발생하는 여러 가지 버그들을 많이 줄일 수 있다.

 

제네릭은 안드로이드와 같은 애플리케이션을 개발할 때 많이 사용되므로 정확하게 알고 있어야 한다.

 

- C++ 언어의 템플레이트와 거의 유사한 기능이다.

 

 

 

제네릭

 

제네릭(Generic) : 클래스를 정의할 때, 구체적인 타입(type)을 적지 않고 변수 형태로 적어 놓는 것이다

 

클래스를 선언하여 객체를 생성할 때, 구체적인 타입을 기재한다. 즉, 타입을 어떤 클래스 종류의 매개변수로 보는 것이다.

 

기존의 방법 : 이전에는 아래와 같이 Object 타입으로 객체를 받아서 다형성을 이용했는데, 그 이유는 모든 객체가 Object 클래스를 상속하므로 다양한 형태의 데이터를 담을 수 있었기 때문이다.

 

public class PrevBox {

private Object data;


public void set(Object data) { 

this.data = data; 

}


public Object get() { 

return data; 

}

}

  • , get() 메소드로 저장한 객체를 반환받을 때 원하는 타입으로 캐스팅(Casting)해야 하는 번거로움이 있었다.

 

제네릭 기법


//제네릭 클래스

public class Box<T> { // T는 타입을 의미한다.

private T data;


public void set(T data) { 

this.data = data; 

}


public T get() { 

return data; 

}

}

  • 위의 클래스를 선언할 때아래와 같이 구체적인 타입을 기재하여 제네릭 클래스를 사용한다.

Box<String> strBox = new Box<String>(); // String 타입만 저장한다.

Box<Integer> intBox = new Box<Integer>(); // Integer 타입만 저장한다.

 

제네릭 클래스(Genenric class)에서는 타입을 변수로 표시한다. 이것을 타입 매개변수(type parameter)”라고 하며, 타입 매개변수는 객체 생성 시에 프로그래머에 의하여 결정된다.

 

 

 

타입 매개변수의 표기

 

제네릭 클래스는 여러 개의 타입 매개변수를 가질 수 있으나 타입의 이름은 클래스나 인터페이스 안에서 유일하여야 한다.

 

관례에 의하여 타입의 이름은 하나의 대문자로 한다.

 

대문자로 하는 이유는 변수의 이름과 타입의 이름을 구별할 수 있게 하기 위함이다.

 

아래는 일반적으로 널리 사용되는 타입의 이름들이다.

  • E Element(요소 : 자바 컬렉션 라이브러리에서 많이 사용된다.)

  • K Key

  • N Number

  • T Type

  • V Value

  • S, U, V 2번째, 3번째, 4번째 타입

 

다이아몬드 : 자바 SE 7버전부터는 제네릭 클래스의 생성자를 호출할 때, 타입 인수를 구체적으로 주지 않아도 된다. 컴파일러가 문맥에서 타입을 추측하기 때문이다. “<>”를 다이아몬드라고 표현한다.

 

Box<String> Box = new Box<>(); //Box<String> strBox = new Box<String>(); 와 같다.

 

다중 타입 매개변수(Multiple Type Parameters)

interface Pair<K, V> {
	public K getKey();
	public V getValue();
}

public class OrderedPair<K, V> implements Pair<K, V> {
	private K key;
	private V value;
 
	public OrderedPair(K key, V value) {
		this.key = key;
		this.value = value;
	}
 
	public K getKey() { 
		return key; 
	}
	
	public V getValue() { 
		return value; 
	}
}


public class PairTest {
	public static void main(String[] args) {
		Pair<String, Integer> pair1 = new OrderedPair<String, Integer>(“Even”, 8);
		Pair<String, String> pair2 = new OrderedPair<String, String>(“Hi”, “nice~”);
		 
		//pair1과 pair2는 인터페이서 Pair 참조 변수로 선언되었다.
		//new OrderPair<String, Integer>은 K를 String으로 실체화하고, V를 Integer로 실체화한다.
		//오토박싱(autoboxing)에 의하여 int(위의 값 8)가 Integer 객체로 자동 변환된다.
		//오토박싱이란 기초 자료형을 대응되는 클래스 객체로 자동 변환해주는 기능이다.
		 
		//또는 아래와 같은 방식도 가능하다.
		 
		//Pair<String, Integer> pair1 = new OrderedPair<>(“Even”, 8);
		//Pair<String, String> pair2 = new OrderedPair<>(“Hi”, “nice~”);
 	}
}


- Raw 타입 : 타입 매개변수가 없는 제네릭 클래스의 이름이다.

 

Box<Integer> intBox = new Box<>(); //기존 방식

Box rawBox = new Box(); //Raw 방식

  • 주의할 점은 처음부터 제네릭 클래스가 아니면 Raw 타입이라고 하지 않는다.

  • Raw 타입은 JDK 5.0 이전에는 제네릭이 없었기 때문에 이전 코드와 호환성을 유지하기 위해 등장하였다. , 타입을 주지 않으면 무조건 Object 타입으로 간주하는 것이다.

 

 

 

제네릭 메소드

 

일반 클래스의 메소드에서도 타입 매개변수를 사용하여 제네릭 메소드를 정의할 수 있다.

 

제네릭 메소드에서의 타입 매개변수의 범위는 메소드 내부로 제한된다.

 

아래는 실제 Array 클래스에 있는 제네릭 메소드의 일부이다.

 

public class Array {

...

public static <T> T getLast(T[] a)

{

return a[a.length-1];

}

...

}

 

타입 매개변수(<T>)는 반드시 메소드의 수식자(public, static)와 반환형(T) 사이에 위치되어야 한다.


 public static <T> T getLast(T[] a)


제네릭 메소드를 호출하기 위해서는 실제 타입을 꺽쇠괄호 안에 넣어주어도 되고 생략하여도 된다.

 

String[] name = {“김철수”, “김영희”, “김숙자”, “김말년”};

String last = Array.<String>getLast(name);

String last = Array.getLast(name); // 컴파일러는 이미 타입 정보를 알고 있다!

 

한정된 타입 매개변수 : 타입 매개변수로 전달되는 타입의 종류를 제한하기 위한 기능으로 extends 키워드를 사용한다.

  • 아래는 한정된 타입 매개변수를 표현하는데 잘못된 예시이다. Array 클래스로 계속 예를 들면,

public class Array {

...

public static <T> T getMax(T[] a) {

if (a == null || a.length = 0) return null;

 

T largest = a[0];

 

for(int i = 1; i < a.length; i++) {

if (largest.compareTo(a[i]) > 0) largest = a[i];

}


return largest;

}

...

}

  • 위의 예시에서 TcompareTo()라고 하는 Comparable 인터페이스를 구현해야 한다. 따라서 클래스의 범위를 Comparable 인터페이스를 구현한 클래스로 제한하는 것이 바람직하다.

  • 아래는 위의 메소드 getMax()를 올바르게 변경한 것이다.

public static <T extends Comparable> T getMax(T[] a) {

...

}

  • “T extends Comparable”은 타입 TComparable 인터페이스를 구현한 클래스들에 대해서만 호출될 수 있음을 의미한다.

  • implements 키워드가 아닌 extends 키워드를 사용하는 것에 주의해야 한다. 이를 통해 타입 매개변수에 상속관계가 성립함을 추측할 수 있다.

 

 

 

제네릭과 상속

 

- 제네릭에서는 타입 매개변수에 상속관계가 성립한다.


 예를 들어 Number를 타입 매개변수로 주어 객체를 생성했다면, Number의 자식 클래스인 Integer, Double, Float 객체도 모두 처리할 수 있다. 맨 처음 작성했던 제네릭 클래스인 Box 를 사용해보자.


public class Box<T> {

private T data;


public void set(T data) { 

this.data = data; 

}


public T get() { 

return data; 

}

}

 

Box<Number> box = new Box<Number>(); // 객체 생성 시 구체적인 타입을 기재한다.

box.add(new Integer(10)); // 타입의 하위 클래스들도 모두 처리된다.

box.add(new Double(10.1));

box.add(new Float(0.0));

 

- 제네릭에서의 상속에서는 한 가지 주의할 점이 있다.


 타입 매개변수에서 상속관계가 성립하는 것과 어떤 타입 매개변수를 가진 제네릭 클래스에서 상속관계가 성립하는 것은 서로 다르다는 것이다.

 

public void exMethod(Box<Number> number) { ... }

 

 위와 같은 메소드에서는 Box<Integer>Box<Double>과 같은 제네릭 클래스는 매개변수로 대입할 수 없다. 그 이유는 Integer 와 Double은 Number와 상속관계가 성립하지만 Box<Integer> 와 Box<Double>은 Box<Number> 와 상속관계가 성립하지 않기 때문이다. 쉽게 아래의 그림을 보면 차이를 알 수 있다.



 그러나 Box<Number>와 Box<Integer>, Box<Double> 사이에 상속관계가 성립할 수 있다.

 

제네릭 클래스의 상속 : 제네릭 클래스들 간의 상속도 일반 클래스처럼 extendsimplements 키워드를 사용하여 표시할 수 있다아래는 나중에 배울 컬렉션 클래스의 일부이다.


ArrayList<E> implements List<E> { ... }

List<E> extends Collection<E> { ... }

 

 즉, Collection ← List<String> ← ArrayList<String> 순서로 부모 ← 자식 상속관계가 생긴다.

 

 

 

와일드 카드

 

와일드 카드(Wild Card) : 제네릭을 사용하는 코드에서 타입 매개변수를 기재하는 꺽쇠괄호 속 물음표(?)로 표현되며, 카드 게임에서 조커와 유사한 역할을 한다. , 어떤 타입이던지 나타낼 수 있다.

 

와일드 카드는 매개변수, 필드, 지역 변수의 타입을 나타내는 등 다양하게 사용된다.

 

상한이 있는 와일드 카드 : 전체 타입이 아닌 일정한 상한이 있는 타입을 표시하는데 사용된다


 코드를 작성할 때, <? extends (상한)> 과 같이 작성한다. 예를 들어 List<Integer>, List<Double>, List<Number>에만 적용되는 메소드를 작성하고 싶다면, Integer, Double 클래스는 모두 Number 클래스를 상속받기 때문에 아래와 같이 작성하면 된다.

 

public static void exMethod(List<? extends Number> list) { ... }

 

 List<? extends Number>의 의미는 Number를 상속받은 어떤 클래스도 ? 자리에 올 수 있다는 것을 의미한다. 이는List<Number>보다는 적용 대상을 넓힌 것이다. List<Number>는 타입 매개변수로 Number에 대해서만 매치되지만 List<? extends Number>Number의 자식클래스까지도 타입 매개변수로 매치되기 때문이다.

 

public static double sumOfList(List<? extends Number> list) {

double s = 0.0;

 

for(Number n : list) {

s += n.doubleValue();

}

 

return s;

}


public static void main(String[] args) {

List<Integer> li = Arrays.asList(1, 2, 3, 4, 5);

System.out.println(“sum = ” + sumOfList(li));

}

 

[출력 결과]

List<Integer> 타입의 li 가 List<? extends Number> 타입을 매개변수로 받는 sumOfList의 메소드에 적용된다.



하한이 있는 와일드 카드 : 특정한 타입을 가진 모든 객체에 대해 작동할 때 사용되는 카드로, <? super (하한)>와 같은 문법을 사용한다.


 예를 들어 Integer 객체를 가질 수 있는 모든 객체를 리스트에 추가하는 메소드를 작성한다면, List<Integer>, List<Number>, List<Object>와 같은 Integer 값을 가지고 있는 모든 객체에 대하여 해당 메소드를 적용시킬 수 있다.

 

public static void addNumbers(List<? super Integer> list) {

for(int i = 1; I <= 10; i++) {

list.add(i);

}

}

 


한도가 없는 와일드 카드 : 모든 타입에 매치되는 와일드 카드로, 단순히 <?> 표현된다. , List<?> 라고 코드를 작성하면 모든 타입의 리스트를 사용하게 되는 것이다.


 주의할 점은 List<?>List<Object>는 혼동할 수 있으나 차이가 있다는 것이다.

 

public static void printList(List<Object> list) {

for(Object element : list) {

System.out.println(element + ", ");

}


System.out.println();

}

 

 위의 경우 printList() 메소드는 Object 객체의 리스트(List<Object>)만 출력할 수 있다. 그 이유는 List<Integer>, List<String>, List<Double>와 같은 클래스들은 List<Object>의 자식이 아니기 때문이다.


 앞에서 언급했듯이 타입 매개변수 간의 상속관계가 성립한 것이지 클래스간의 상속관계는 성립되지 않았다.


 아래는 모든 타입에 매치되는 리스트를 매개변수로 받을 수 있는 올바르게 작성된 코드이다.

 

public static void printList(List<?> list) {

for(Object element : list) {

System.out.println(element + “, ”);

}


System.out.println();

}

 

 





 

 

Switching

 

- 다수의 기기를 unicast 방식으로 서로 통신할 수 있도록 중간 장치(switch, router)를 설치하는 방법 (사실 multicast, broadcast 도 지원한다.)

 

- Point-to-Point(점대점) 연결 방식이다.

 

- Switch : 스위치에 연결된 둘 또는 다수의 기기들 사이에 일시적인 연결을 만들게 하는 하드웨어 또는 소프트웨어적인 기기이다. 스위치에 꼽힌 케이블을 통해 목적지 포트를 향해 데이터들이 전송된다. 계층별로 있으며 2계층 장비는 L2 스위치, 3계층은 L3 스위치라고 부른다.

 

- 스위치는 기기간의 연결이 아닌 중간장치의 역할이며, 하드웨어적인 기기의 경우 속도가 빠르나 유연성이 낮고 비용이 많이 든다.

 

 

 

Switched Network

 

- 회선 교환 방식(Circuit-Switched Networks)

 

- 패킷 교환 방식(Packet-Switched Netwoks)

  • 데이터그램 방식(Datagram Networks)

  • 가상 회선 방식 (Virtual-Circuit Networks)

 

- 메시지 교환 방식(Message-Switched Networks)

 

 

 

TCP/IP 통신 계층들과 스위칭 방식

 

- 물리 계층(Physical Layer, 1계층) : 회선 교환 방식이 이루어지며, 신호들이 하나의 경로 또는 다른 경로에서 이동한다.

 

- 데이터 링크 계층(Data-Link Layer, 2계층) : 패킷 교환 방식이 이루어지며, 일반적으로 가상회선 방식을 이용한다.

 

- 네트워크 계층(Network Layer, 3계층) : 패킷 교환 방식이 이루어지며, 가상 회선 방식과 데이터그램 방식 둘 다 이용한다.

 

- 응용 계층(Application Layer, 7계층) : 메시지 교환 방식을 이용한다.

 

 

 

회선 교환 방식의 네트워크 (Circuit-Switched Network)

 

- 물리 계층에 연결된 스위치들로 이루어진다. , 주로 물리 계층에서 작용하는 네트워크로 하드웨어 측면에서 속도가 빠르다.

 

- 출발지와 목적지 사이의 하나의 연결이 하나 또는 다수의 링크들로 만들어진 망 자원을 전용으로 할당받는다.

 

- 각각의 링크는 주파수 분할 다중화(FDM) 또는 시 분할 다중화(TDM) 방식에 의해 n개의 채널들로 나누어 진다.

 

- 망이 전용자원으로서 할당되기 때문에 다른 사용자와 함께 사용할 수 없으므로 전송 중에 다른 데이터가 끼어들 수도 없다.

 

- 연결 개수가 제한되기 때문에 연결의 전체 시간측면에서 효율성이 떨어진다.

 

- 주로 전화망에서 사용하는 스위칭 방식이다.

 

- 연결 설정 단계 : 미리 연결을 설정한다. 이를 우리는 셋업 절차(setup)라고 표현한다.

  • 데이터 전송 단계에서 이용되어질 자원을 예약한다.

  • 이 자원들은 채널(타임 슬롯이나 주파수), 버퍼, 처리 시간, 입출력 포트를 의미하며, 데이터 전송 동안은 전용으로 할당되어진다.

  • 종단간의 주소(End-to-end addressing)가 이용되어진다. ex) 출발지 및 목적지 IP 주소

 

- 데이터 전송 단계

  • 데이터(세그먼트)는 패킷으로 분할되지 않고, 하나의 연속적인 흐름으로 전송된다.

  • 주소는 헤더의 필드값에 저장되므로 데이터는 주소를 포함하지 않는다.

 

- 연결 해제 단계

  • 자원을 해제한다.

 

- 미리 연결 설정하여 전용 자원을 할당하므로 실제 데이터만 전송할 때는 지연(delay)없이 데이터가 쭉 흘러간다.

 

 

 

회선 교환 방식의 네트워크 (Packet-Switched Network)

 

- 상위 계층(전송 계층, 4계층)에서 세그먼트가 캡슐화되어 3계층에 내려오면, 데이터그램이 되는데, 데이터그램은 세그먼트(4계층 헤더+데이터)3계층 헤더(IP헤더)를 포함한다. , 오버헤드

 

- 상위계층으로부터 도착한 메시지(데이터그램)가 고정되거나 가변적인 크기의 패킷들로 나뉘어진다.

 

- 패킷에 대한 전용자원을 할당하지 않는다.

 

- FIFO(First-In-First-Out) 방식을 기반으로 자원이 할당된다.

 

- 스위치나 라우터에 큐(Queue)라는 버퍼가 있는데 버퍼가 꽉차면 큐잉 지연이 발생할 수 있다.

 

- Store-and-forward 방식 : 큐에 저장했다가 어디로 내보낼지 정한 뒤, 스위치(또는 라우터) 내부에 입력 버퍼에서 출력버퍼로 포워딩(forwarding)하는 방식이다.

 

- 주로 컴퓨터 통신에 이용되어진다. 데이터가 폭발적이므로 연결설정을 하지 않는다.

 

- 데이터를 패킷 단위로 작게 쪼개는 이유 : 메시지(데이터)가 클수록 오류 검출을 위한 오버헤드가 커지게 된다

 

 

 

데이터그램 방식의 네트워크 (Datagram Network)

 

- 패킷 교환 방식 중 하나로, 데이터그램이 패킷들로 분해된 후 각각의 패킷(나뉜 데이터그램)은 독립적으로 여겨진다.

 

- 연결 설정 단계가 없다.

 

- 수신측에서는 패킷들을 다 받아서 하나의 데이터그램으로 조합한다. 이 때, 패킷들 사이에 지연(delay)가 발생하여 데이터그램들이 목적지에 도착하는 순서가 어긋날 수 있다. 패킷이 하나라도 없으면 조합할 수 없기 때문이다.

 

- 패킷들은 전송 중에 손실되거나, 버퍼가 가득 차서 오버플로우가 발생하면 버려질 수 있다.

 

- 네트워크 계층(3계층)에서 주로 이용되는 방식이다.

 

- 링크를 사용자들이 돌아가면서 사용하기 때문에 하나의 링크를 이용할 수 있는 사용자 수가 많다. 따라서 회선 교환 방식보다 효율성이 높다.

 

- 라우터는 라우팅 프로토콜(Routing Protocol)이 만든 포워딩 테이블을 이용하는데, 포워딩 테이블에는 목적지 IP주소와 출력 포트번호가 저장되어 있다.

 

- 라우터는 패킷의 헤더에 있는 목적지 IP주소와 포워딩 테이블에 있는 IP주소를 비교한 뒤, 해당 IP주소에 맞는 출력 포트로 패킷을 포워딩한다. 모든 경로가 이런 방식으로 안내되어진다.

 

- 전체 지연 시간 = (transmission delay) + (hop )*(propagation delay) + (processing delay) + (queueing delay)

 

 

 

가상 회선 방식의 네트워크 (Virtual-Circuit Network)

 

- 회선 교환 방식과 패킷 교환 방식의 혼합방식이다.

 

- 패킷 교환 방식 중 하나이지만, 연결 지향적인 네트워크로서 연결 설정 단계가 있다.

 

- 자원들은 셋업 절차나 필요 시에만 할당될 수 있다.

 

- 데이터는 패킷화되어지고, 각 패킷들은 연결 식별자(Virtual-Circuit Identifier, VCI)를 옮긴다.

 

- 모든 패킷들은 연결단계에서 설정된, 같은 경로를 따른다. 따라서 순서에 맞게 간다.

 

- 보통 데이터 링크 계층(2계층)에서 구현되며, 속도가 빠르다.

 

- 연결 단계에서 Global unique 주소가 연결 식별자(VCI)를 만들기 위해서만 이용되어진다.

 

- VCI는 스위치가 직접 관리하는 식별자로, 실질적으로 데이터를 전송할 때 이용된다. 숫자가 작고 Locally unique 주소라서 오버헤드가 축소된다.

 

- Label Swapping : 스위치를 지날 때마다 VCI를 바꾸는 것으로, 현 스위치가 식별하는 값을 다음 스위치가 식별할 수 있는 값으로 변경하는 것이다.

 

- 연결 설정 단계 : 연결에 필요한 VCI 테이블을 만들기 위해 출발지와 목적지의 글로벌 주소가 이용된다.

 

- 데이터 전송 단계 : 입력 포트 번호 및 VCI를 기반으로, 스위치가 출력 포트 번호 및 VCI를 찾기 위해 VCI 테이블을 탐색한다.

 

- 연결 해제 단계 : VCI 테이블의 VCI값은 이 단계에서 저장되어지며, 대응하는 entry들을 없앤다는 것을 스위치에게 알린다.






+ Recent posts