반응형

0. 네트워크는?

네트워크(Network)의 어원은 Net+work로 '그물을 짜는 일'에서 나왔다고 합니다.

네트워크는 의미있는 정보인 데이터를 전송하는 복잡한 그물이라고 볼 수도 있겠네요.

 

하지만, 만약 누군가에게 네트워크의 정의에 대해 말해줄 일이 생긴다면 아래처럼 말할꺼 같습니다.

 

네트워크란 두 개 이상의 노드가 서로의 자원을 고유할 수 있는 데이터 통신 환경.

 

뭔가 유식해보이는 느낌을 주니까요.ㅎㅎ

 

 

본론으로 들어와서 네트워크는 크게 유선과 무선으로 나눠볼 수 있다고 생각합니다. 무선네트워크라하면 LTE, WiFi 같은 녀석들이 있을 것이고, 유선이라고 한다면 PC와 셋톱박스의 연결되는 인터넷이 대표적이겠죠.

 

앞으로 이러한 네트워크 환경을 구성하는 다양한 프로토콜과 이론들에 대하여 알아보도록 하겠습니다. 먼저 간단한 이론부터 시작하겠습니다.

 

1. 거리 기반 네트워크

종류 범위 특성
PAN (Personal Area Network) 약 5m 전후의 인접 통신 초 인접지역 통신으로 일반적으로 무선의 WPAN이 주
LAN (Local Area Network) 근거리 네트워크로 사무실과 같은 소규모 공간 내의 고속 통신회선 WAN보다 빠른 통신 속도, 단일 기관 소유의 네트워크, Peer-to-Peer 형태가 주
MAN (Metropolitan Area Network) LAN과 WAN의 중간형태 광케이블, 동축케이블을 통한 전송, DQDB 프로토콜
WAN (Wide Area Network) 광대역 네트워크망으로 유관한 LAN간의 연결 목적지를 결정하는 경로 탐색 알고리즘이 중요

 

* DQDB (Distributed Queue Dual Bus) : IEEE 802.6 표준 MAN 프로토콜, 이중 버스형태에 분산 큐를 통한 큐잉방식을 통한 전송방식.

 

 

 

2. 데이터 전송 방식

유무선 통신방식은 크게 3가지 형태로 나눌 수 있습니다.

 

단방향 통신 (Simplex)

일방적으로 'A->B' 의 통신방 가능한 전송방식

Simplex
반이중 통신 (Half Duplex)

서로 데이터를 전송할 수 있지만, 하나의 회선을 사용하기 때문에 동시에 전송은 불가능 (ex, 무전기)

Half Duplex
전이중 통신 (Full Duplex)

서로 언제나 필요한 데이터를 동시에 송수신 할 수 있는 전송 (ex, 전화)

Full Duplex 

 

 

3. 네트워크 토폴로지 (Network Topology)

네트워크 토폴로지는 물리적으로 연결된 형태에 따른 분류라고 볼 수 있으며, 다르게 말해 통신망의 구조에 따른 분류라고도 볼 수 있습니다.

 

크게 '링크'와 '노드'라는 요소로 이루어져있습니다.

 

링크(=회선) : 두 노드를 연결하는 선으로 PC에 연결되는 인터넷선(랜선)을 생각하면 이해하기 좋습니다.

노드 : 뒤에서 다루겠지만, 네트워크의 데이터를 송수신하고, 이 데이터를 처리하는 장치를 말합니다. 대표적으로 PC(단말노드)와 라우터가 있습니다.

 

 

네트워크 토폴로지에 의한 분류는 크게 5가지로 나눌 수 있습니다.

 

계층형 (Tree)

장점

 *. 네트워크 관리가 쉽고, 새로운 장치를 추가하기 쉬움

 * 네트워크의 신뢰도가 높음

 

단점

 * 트래픽 집중에 따른 속도 저하현상(병목현상)이 발생하기 쉬움

 * 상위 노드 고장시 상위 네트워크와의 통신이 불가능

버스형 (Bus)

장점

 * 설치비용이 적고, 신뢰성 우수

 * 구조 간단

 * 새로운 노드 추가가 쉬움

 

단점

 * 네트워크 병목현상 발생이 쉬움

 * 장애 발생시 전체 네트워크 마비

 

특징

 * 회선의 양 종단에는 터미네이터(Terminator)가 존재하여 신호의 반사를 차단합니다.

성형 (Star)

장점

 * 고속 네트워크에 적합

 * 노드 추가가 쉬움

 * 개별 링크 장애시에도 네트워크에 영향이 없음

 

단점

 * 중앙 노드 장애시 전체 네트워크 불통

 * 노드 증가에 따라 네트워크의 복잡도가 증가함

링형 (Ring)

장점

 * 저렴한 네트워크 구성이 가능

 * 충돌현상이 발생하지 않음

 

단점

 * 네트워크의 구성을 변경하기 힘듬

 * 링크 장애시 전체 네트워크 불통

 

특징

 * Token Passing기법을 사용한다.

망형 (Mesh)

장점

 * 완벽하게 이중화 되어있으므로 장애에 강함

 * 많은양의 데이터 처리에도 문제없음

 

단점

 * 구축과 운영 비용이 매우 고가 

반응형
반응형

0. 시작하기

 

앞으로 진행될 거의 모든 내용에서 클래스를 다룰것 같습니다. 또한, 클래스에 사용되는 것들에 대해서만 언급해도 끝이 없습니다. 때문에 다음 내용부터는 대부분 [클래스의 ㅇㅇㅇ]이라는 느낌으로 진행될듯합니다.

 

 

1. 객체지향 프로그래밍 ( OOP : Object Oriented Programing )

사실 객체지향이라는 것에 대해서만 다뤄도 짧지 않습니다만, 간단하게만 집고 넘어가겠습니다.

 

객체지향 프로그래밍이 어떤 것이다라고 정의해둔 글들이 많이 있습니다만, 제 생각에 가장 간단하게 말하자면 아래와 같습니다.

 

객체지향 프로그래밍(OOP)은 프로그램이 사용하는 유관한 데이터들을 조합하여 묶어줌으로 객체(사물, 사람, 대상)를 만들어주고, 여기에 객체가 행할 수 있는 행동을 정의해줌으로써 각 객체가 상호작용을 수행할 수 있는 프로그래밍을 의미한다.


라고 생각합니다. 사람마다 생각하는것에 차이가 있기 때문에 제가 생각하는 객체에 대한 정의가 다른사람이 볼때는 잘못됬다고 생각할 수 있습니다.

어찌되었든 글로 표현하면 이해하기가 힘든 내용입니다. 때문에 간단하게 그림을 통해 알아보겠습니다.

 

먼저 객체의 정의가 필요합니다.

객체의 정의란, 어떤 객체가 취할수 있는 상태(state, 멤버변수)를 정의하고, 객체가 행할 수 있는 행동(Action, 멤버함수)을 정의하는 것입니다.

 

간단하게 사람이라는 객체를 정의한다고하면 아래와 같은 것들을 의미합니다.

 

여기서 중요한 것은 가변하는 값을 갖은 멤버 변수는 이에 대응하는 멤버 함수가 존재해야합니다.

 

예를들어 '몸무게'라는 멤버변수는 '식사하기'라는 멤버함수에 의해서 제어된다는 식의 개념이 필요합니다.

 

물론, 고정되는 값을 갖는 멤버변수도 존재합니다. 만약 위의 데이터가 한달만 사용되는 데이터라면, '나이', '성별'등은 특별한 경우가 아니라면 고정된 값을 갖은 멤버변수일 것입니다.

 

만약 위와같이 멤버변수, 멤버함수를 통해서 객체(=사람)을 정의했다면, 다음은 정의한 객체들을 구분할 이름을 할당합니다.

 

 

 

위와같이 각각의 이름을 할당받은 객체들은 앞서 정의한 기준에 따라 초기화를 해주게됩니다.

 

초기화는 각각의 객체가 갖고있는 상태를 저장하는 것을 말합니다. 예를들어 철수의 현재 나이는 7살이고, 키는 70cm, 몸무게는 20kg등의 정보등을 입력하는 과정을 말합니다.

 

객체의 초기화가 끝나면 각 객체들은 정의해준 멤버함수를 통해서 서로 상호작용이 가능합니다. 물론 단순히 자신의 값만을 변경하는 것도 가능합니다.

 

위와같은 과정을 이제 코드를 통해서 다뤄보겠습니다.

 

2. Class ( CPP/Class.cpp )

객체지향 프로그래밍(OOP : Object Oriented Programing)의 꽃 Class에 대해서 다뤄보겠습니다.

#include <iostream>
using namespace std;

class User{
private:
    int age;
    int tall;
    int weight;
    bool sex; // true: 남성, false: 여성

public:
    void Init(int age, int tall, int weight, bool sex){
        this->age = age;
        this->tall = tall;
        this->weight = weight;
        this->sex = sex;
    }
    void prtInfo(){
        cout << "age : " << age << endl;
        cout << "tall : " << tall << endl;
        cout << "weight : " << weight << endl;
        cout << "sex : " << sex << endl << endl;
    }
};

int main(void){
    User Hun2, Chulsu;
    Hun2.Init(7, 30, 20, true);
    Chulsu.Init(7, 32, 22, true);
    Hun2.prtInfo();
    Chulsu.prtInfo();

    return 0;
}

실행결과

 

정말 간단한 Class 예제입니다.

 

User라는 클래스를 보게되면 먼저 [ private 와 public ]이라는 두가지를 볼 수 있습니다. 바로 '접근제한자'라는 것입니다. 다음에 자세하게 다뤄보겠지만, 간단히 말하면 private는 해당 class내의 함수에서만 해당 변수들에 접근이 가능하다는 것을 말하며, public은 어디서든 해당 함수나 변수에 접근이 가능하다는 것을 말합니다.

 

private 로 선언된 부분에 멤버변수를 적어주었고, public으로 선언한 부분에 멤버함수를 적어주었습니다. private로 멤버변수에 접근하지 못하게 하는것을 '정보은닉'이라고 합니다. 굳이 사용자가 알아야할 정보가 아닌것에 접근하는것을 차단하기 위한 방법이죠.(접근제한자 설명시 다시 언급하겠습니다.)

 

다음으로 this라고 되어있는 부분을 볼 수 있습니다. 'this'는 현재 접극하는 객체의 주소값을 갖고있는 녀석을 말합니다.

 

만약 '훈이'라는 객체가 만들어지고 해당 객체에서 'this'가 포함된 함수를 실행하면, 거기서 'this'는 훈이라는 객체의 주소가됩니다. 따라서 [this->변수]를 통해서 해당 객체가 갖고있는 멤버변수에 접근이 가능합니다.

 

따라서 위의 Init부분을 보게되면 같은 age라는 변수명을 사용했음에도 서로 구분되어 사용이 가능하게됩니다.

 

 

반응형
반응형

0. 시작하기

 

 

1. New 키워드에 대해서

앞에서 동적할당에 대해서 간단하게 말씀드렸습니다. 여기서는 메모리와 연결해서 조금 더 자세하게 알아보도록 하겠습니다.

 

int *pt = new int[10];

위의 간단한 코드를 메모리측에서 보면 Heap영역과 Stack영역을 나눠서 봐야합니다.

 

앞서 다른 게시물에서 언급했듯 Heap영역은 동적할당시 사용되는 메모리 영역이며, Stack영역은 지역변수(변수,포인터, 참조자 등 모두해당됩니다.)가 사용하는 메모리 영역입니다.

 

따라서 위의 과정을 메모리 영역에서 보면 아래와 같은 모습을 볼 수 있습니다.

 

 

int *pt = new int[10] 에 대한 메모리 추상화

 

new int[10] 이라는 코드가 heap영역에 공간을 확보하고 해당 공간의 주소값을 반환한다고 했는데, 확인해보겠습니다.

 

#include <iostream>
using namespace std;

int main(void){
    cout << (new int[10]) << endl;

    return 0;
}

실행결과

 

 

위와같이 new 키워드의 결과를 출력하면 주소값을 반환하는 것을 볼 수 있습니다. 때문에 주소값을 저장하기 위해 포인터(*)를 사용하는 것입니다.

 

위에서 heap영역과 stack영역을 구분해서 말씀드린 이유가 있습니다!!

 

가장 중요한 이유, 그것은 stack영역에 저장되는 데이터는 함수가 종료되는 시점까지만 유효한 값을 갖습니다.(지역변수) 반면 heap영역은 할당받은 메모리를 반환할때까지 유효한 값을 유지합니다.

 

이에대한 두가지 예제를 보겠습니다.

 

첫번째는 stack 영역에 저장된 값의 주소를 반환한 경우입니다.

 

#include <iostream>
using namespace std;

int* func(){
    int x=10;
    return &x;
}


int main(void){
    int *pt = func();
    cout << *pt << " : " << pt << endl;

    return 0;
}

경고 메시지
실행결과

 

해당 코드를 실행하면 위와같은 [경고메시지]와 [실행결과]를 볼 수 있습니다.

 

다음으로는 heap 영역에 저장된 값의 주소를 반환하는 경우입니다.

 

#include <iostream>
using namespace std;

int* func(){
    int *x = new int;
    *x = 10;
    return x;
}


int main(void){
    int *pt = func();
    cout << *pt << " : " << pt << endl;

    return 0;
}

실행결과

 

후자에서는 [경고메시지]없이 [실행결과]를 얻을 수 있었습니다.

 

의문이 들 수 있습니다. [경고메시지가 출력되기는 했지만, 실행만 잘 되면 괜찮은거 아닌가요?] 라는 의문.

 

답은 절대로 안됩니다!

 

 

 

여러분이 프로그램을 설계할 때, 심심하면 한번씩 이상한 값을 출력하길 원하는게 아니라면, 절대 위와같은 경고메시지(⚠️)를 무시하시면 안됩니다.

 

위의 경고메시지가 발생하는 원인은 한가지 입니다.

 

-> 유요하지 않은 값, 즉 해당 메모리는 다른 값에 의해서 언제든지 덮에 씌워질 수 있는 상태라는 것입니다.

 

새로운 값이 스택영역에 저장되면 해당 공간에는 다른 값이 저장되고, 그때는 10이 아닌 다른 값을 출력할 것입니다. [경고메시지]의 출력을 제거한 상태라면 위와같은 문제로 프로그램이 꼬였을 때, 문제를 찾기도 힘들죠.

 

반면 후자에서 사용한 heap영역의 주소를 반환했을 때에는 함수가 종료된 후에도 [heap 영역의 데이터] 가 유효한 상태를 유지하기 때문입니다. heap영역의 데이터는 프로그램이 종료되거나, 해당 공간을 os에 반환할 때까지 유효한 값을 갖습니다.

 

 

 

OS로부터 할당받은 공간을 사용 후 반환, 그리고 다시 해당 값을 참조하는 것은?

 

이건 더 큰 문제를 야기할 수 있습니다. heap영역은 가변가능한 공간입니다. 사용하지 않을경우 OS에 반환(또는 회수)되는 공간이죠.

 

이렇게 반환된 공간은 다른 프로그램에 의해서 사용될 수 있습니다.

 

운이 나쁘다면(?) 반환된 공간을 참조함에따라 다른 프로그램이 사용중인 영역의 값을 프로그램이 요청하게되고, 이것은 운영체제의 프로세스 관리 규칙에 위배됨에따라 강제로 해당 프로그램이 종료되는 문제를 발생시킬 수 있습니다.

 

 

 

2. Delete 키워드에 대해서

사실 New 키워드에 대해서 자세히 다룬 덕분에 delete에 대해서는 크게 말씀드리게 없습니다.

 

단일 객체에 대한 할당을 제거할 시 delete를 사용하고, 배열 객체에 대한 할당 제서기 delete[]를 사용한다는 차이와 delete를 사용한 후에도 해당 영역에 대한 참조가 가능하지만, 실제로 접근하면 new키워드의 마지만 부분에서 언급했던 문제와 같은 일이 생길 수 있다는 것만 말씀드리면 될 듯합니다.

 

 

 


...더보기

해당내용은 사용하는 운영체제(OS)와 컴파일러, IDE에 따라서 차이가 있을 수 있는 내용입니다.

반응형

+ Recent posts