그래프 (Graph)

그래프는 정점(Vertex)과 간선(Edge)로 이루어진 자료구조로, 정점간의 연결관계를 나타냅니다.

  • 정점(Vertex) : 데이터를 표현하는데 사용한다.
  • 간선(Edge) : 두 정점을 연결하며, 관계를 나타낸다.

 

특징 및 종류

  • 네트워크 모델
  • 2개 이상의 경로가 가능하다.
  • 부모-자식 관계 / 루트 노드 개념이 없다
  • 순환 / 비순환  그래프
    • 순환(Cycle) : 동일한 정점에서 시작하여 다시 그 정점으로 돌아오는 경로. 순환이 있는 그래프
    • 비순환(Acyclic) : 그래프 내에 순환이 없는 그래프
  • 방향 / 무방향 그래프
    • 방향 그래프 (Directed Graph) : 간선이 방향성을 가지고 있는 그래프
    • 무방향 그래프 (Undirected Graph) : 간선간의 방향이 없는 그래프로 서로 모두 이용 가능한 상태
  • 가중치 그래프
    • 가중치 (Weighted Graph) : 간선에 비용이나 가중치가 할당된 그래프
  • 연결 / 비연결 그래프
    • 연결 (Connected Graph) : 무방향 그래프에 있는 모든 정점에 대해서 경로가 존재하는 그래프
    • 비연결 (DisConnected Graph) : 무방향 그래프에서 특정 정점 사이에 경로가 존재하지 않는 경우
  • 완전 그래프
    • 완전(Complete Graph) : 그래프에 속해있는 모든 정점이 서로 연결되어 있는 그래프

 

 

행렬 / 리스트 표현 방식 - https://howtolivelikehuman.tistory.com/75

인접 리스트 

  • 각 정점마다 연결된 정점들을 리스트로 저장하는 방식
  • 메모리 사용량 O(V + E)이며, 인접 행렬보다 메모리 사용이 효율적이다.
  • 그래프 내의 적은 숫자의 간선을 가지는 그래프(희소 그래프)인 경우에 사용하기 적합하다.
  • 인접 노드를 빠르게 알 수 있지만, 연결 여부확인은 모든 노드를 탐색해야한다.

 

enum Vertex { A, B, C, D, E, F };

class Graph
{
private:
	int vertices;								             
	std::vector<std::vector<Vertex>> adjList;
public:
	void addEdge(Vertex u, Vertex v)
	{
		adjList[u].push_back(v);
		adjList[v].push_back(u);
	}
};

int main() {
	graph.addEdge(A, B);
	graph.addEdge(B, C);
	graph.addEdge(B, D);
	graph.addEdge(C, E);
	graph.addEdge(D, F);
}

 

 

인접 행렬

  • 정점간의 연결 여부를 2D 행렬(2차원 배열)로 표현하는 방식
  • 메모리 사용량은 O(V^2)이며, 인접 리스트보다 상대적으로 메모리를 더 많이 사용한다.
  • 노드간의 연결 정보를 바로 알 수 있으며, 구현이 쉽다 (탐색 속도 O(1))
  • 간선의 연결 여부는 빠르게 알 수 있지만, 어떤 노드에 인접한 노드를 찾기 위해서는 모든 노드를 순회해야한다.
  • 간선이 많이 존재하는 그래프(밀집 그래프) 형태에 사용하기 적합하다.
class arrGraph
{
private:
	int vertices;
	std::vector<std::vector<int>> adjMatrix;

public:
	void addEdge(int u, int v)
	{
		adjMatrix[u][v] = 1;
		adjMatrix[v][u] = 1;
	}
};

int main() {
	graph.addEdge(0, 1);
	graph.addEdge(1, 2);
	graph.addEdge(1, 3);
	graph.addEdge(2, 4);
	graph.addEdge(3, 4);
	graph.addEdge(3, 5);
  
	return 0;
}

이번 포스팅에서는 네트워크에서 데이터들이 어떻게 송/수신되는지에 대한 과정에 대해 알아보려고 합니다.

호스트네임 또는 IP와 포트번호를 통해 송신과 수신을 어떻게 하는지, 그리고 데이터를 전송하는 과정에서의

UDP와 TCP의 전송방식, 특징 및 차이점에 대해 알아보겠습니다.

 

OSI 7계층 / TCP/IP 4계층

OSI 7계층 / TCP/IP 4계층 비교 - https://shlee0882.tistory.com/110

 

※ OSI 7계층 : 네트워크에서 통신이 일어나는 개념적인 과정을 7단계로 나눈 것

※ TCP/IP 4계층 : 네트워크에서 실제로 사용하는 인터넷 표준을 4단계로 나눈 것

 

  • 4층 - 어플리케이션 계층 - HTTP, DNS, FTP 등
  • 3층 - 전송 계층 - TCP, UDP
  • 2층 - 인터넷 - IP
  • 1층 - 네트워크 엑세스 계층 - 이더넷

 

IP(Internet Protocol)

  • TCP와 UDP가 데이터를 전달하는데 사용하는 기본 전송 수단.
  • 데이터를 패킷(Packet)단위로 나누어 전송하고, 목적지 IP 주소를 기반으로 라우팅한다.
  • 비연결성이며, 신뢰성이 보장되지 않는다.
    • 데이터가 유실되거나 순서가 보장되지 않는다.

※ 패킷 (Packet) : 네트워크를 통해 전송되는 형식화된 데이터 덩어리

  • 라우터마다 패킷 한개의 크기가 제한되어있다 .(600 ~9000바이트, 평균 1300)
  • 주고받는 데이터, 페이로드의 크기 및 송/수신자 주소, 체크섬 등이 들어있다.
    • 수신자 주소 : 수신측 단말기까지 전달할 때 라우터에서 필요한 정보
    • 송신자 주소 : 수신측 단말기까지 도착한 후 수신자 측에서 송신자를 식별하는 용도
    • 체크섬 : 메시지를 검증해주는 데이터

 

UDP(User Datagram Protocol)

전송 계층의 통신 프로토콜 중 하나로, 사용자가 정의한 데이터그램을 상대방에게 보낼 수 있게하는 통신 규약입니다.

 

출처 : https://mangkyu.tistory.com/15

 

  • 비 연결지향적 프로토콜
  • 데이터 전달 및 순서 보장을 하지 않는다.
  • UDP 헤더의 체크섬 필드를 통해 최소한의 오류만 검출한다.
  • TCP보다 속도가 빠르며, 빠른 요청과 응답이 필요한 실시간 응용에 사용된다.
    • 데이터그램 유실이 생겨도 이어서 오는 데이터가 해당 정보를 보완해주는것들을 UDP로 전송한다.
    • Ex) 캐릭터 이동 정보
    • 음성, 화상데이터 전송
  • 1:1, 1:N, N:N 형태의 통신이 가능하다.
  • 데이터그램(메시지) 단위로 전송되며, 메시지의 크기가 어플리케이션 크기에 의해 정의된다.
  • 소켓을 활용하여 IP와 PORT를 기반으로 데이터를 전송한다.

 

TCP(Transmission Control Protocol)

전송 계층의 통신 프로토콜 중 하나로, 전송제어를 통해 송/수신데이터가 완전히 동일함을 도장하는 프로토콜 입니다.

ACK / NACK - https://www.geeksforgeeks.org/snooping-tcp/

 

  • 연결지향형(Connection Oriented)식으로, 1:1 통신만 가능하다.
  • 흐름제어기능(Data Flow Control)을 통해 데이터 전송을 보장한다.
    • 데이터가 상대방에게 정확하게 전송되는것을 보장하는 기능
  • 스트림 데이터 형식으로 전송한다.
    • 세그먼트(Segment)라는 IP 패킷에 넣을 수 있는 크기의 단위로 쪼개어 전송
      (송신 단말기 A -> 수신 단말기 B) 
    • IP패킷을 받으면 세그먼트를 꺼내 받은 세그먼트 응답을 송신자에게 반송
      (수신 단말기 B -> 송신 단말기 A)
      • 해당반송 과정을 ack, acknowledge라고 한다.
    • 즉, ack가 회신되지 않은 경우 상대방이 받았다는 응답이 올때까지 다시 세그먼트를 전송하여 송/수신 전송을 보장한다.
  • 패킷에 대한 응답을 하기전까지 블로킹되며, UDP에 비해 속도가 느리다.
  • 연결 시 TCP 3-Way Handshake을 통해 연결을 설정한다.
    1. SYN : 연결을 생성할 때 클라이언트가 서버에 시퀀스 번호를 보내는 패킷
    2. SYN-ACK :  시퀀스 번호를 받은 서버가 ACK값을 생성하여 클라이언트에게 응답하는 패킷
    3. ACK : ACK 값을 사용하여 응답하는 패킷
  • 연결 종료시에는 TCP 4-Way Handshake 방식을 통해 연결을 종료한다.
    1. FIN : 클라이언트가 연결을 종료하고 싶을 때 FIN플래그가 설정된 패킷을 전송
    2. ACK : 시퀀스 번호를 받은 서버가 클라이언트의 종료 요청 확인
    3. FIN : 서버가 종료되었음을 알림과 동시에 클라이언트에게 자신의 시퀀스 번호를 보내는 패킷
    4. ACK : ACK값을 확인하여 서버 종료 요청 확인하는 패킷

 

TCP vs UDP 비교

 

특성 TCP (Stream) UDP (Message)
전송 단위 바이트 스트림 (경계 없음) 메시지 (데이터그램, 경계 유지)
신뢰성 데이터 손실, 순서 보장, 중복 방지 신뢰성 없음
연결성 연결형 (Connection-oriented) 비연결형 (Connectionless)
속도 느림 (추가적인 신뢰성 처리) 빠름 (신뢰성 처리 없음)
사용 사례 파일 전송, 웹 브라우징 (HTTP, FTP 등) 실시간 스트리밍, VoIP, 게임 데이터 전송

 

 

'OS , 네트워크' 카테고리의 다른 글

동기, 비동기, 블로킹, 논블로킹  (1) 2025.03.11
OSI 7계층  (0) 2025.03.10
TCP/IP 4계층  (0) 2025.02.06
프로세스 동기화 - 세마포어, 뮤텍스, 임계영역  (1) 2025.01.03

프로세스 동기화

프로세스와 스레드들은 내부에서 스레드끼리 자원을 공유하며, 이 과정에서 자원의 순서와 같은 일관성을 보장해야 하기위해 동기화가 되어야합니다.

즉, 프로세스들 사이의 실행순서를 조정하는 방법입니다.

공유된 자원에 대한 멀티 프로세스 및 멀티 스레드 환경에서 동시접근에 대한 일관성을 보장하기위해 다양한 방법들이 있으며 그중 임계영역(Critical Section), 뮤텍스(Mutex), 세마포어(Semaphore)에 대해 알아보겠습니다.

 

임계영역(Critical Section)

멀티프로세스 환경에서 둘 이상의 프로세스가 동시에 접근해서는 안되는 데이터 및 코드들의 영역입니다.

임계영역에 동시에 접근하는것을 방지하여 자원의 일관성 및 원자성을 지키기 위해 한번에 하나의 프로세스 또는 스레드만 실행할 수 있도록 보호하는 영역입니다.

  • 임계 영역에 접근하기 위해 동기화 메커니즘(세마포어, 뮤텍스 등)이 필요하다.
  • 여러 스레드가 동시에 진입하면 데이터의 무결성(일관성)이 지켜지지 않는다.
  • 동기화 메커니즘이 없는 경우, 레이스 컨디션(Race Condition)이 발생할 수 있다.
    • 임계구역에 동시에 접근하여 자원의 일관성이 깨지는 경우

 

이러한 임계영역의 사용 및 원자성과 일관성을 보호하기위한 방법은 세가지 원칙을 가지고 있습니다.

  1. 상호 배제 (Mutual Exclusion) : 한 번에 하나의 프로세스 또는 스레드만 임계영역에 진입하도록 보장하는 원칙
  2. 진행 (Progress) : 임계 영역에 접근하려는 프로세스 또는 스레드가 있을 때, 접근한 프로세스 중 하나가 반드시 선택되어야한다.
  3. 한정된 대기 (Bounded Waiting) : 프로세스가 임계영역에 접근하기 위해 대기할 떄 그 대기시간이 한정되있어야한다.

 

뮤텍스 (MUTual EXclusion)

MUTual EXclusion, 상호배제입니다. 멀티 프로세스 및 멀티 스레드 환경에서 임계영역을 가진 스레드들의 공유 불가능한 자원의 동시 사용을 막기위해 사용되는 알고리즘으로, 임계구역에서 구현됩니다.

멀티 프로세스들의 공유 자원에 대한 접근을 제한하기위해 Lock과 Unlock를 사용합니다.

  • 멀티 프로세스 및 멀티스레드 환경에서 공유자원의 동시 사용을 방지해 원자성을 유지한다.
  • lock 과 Unlock을 사용하여 스레드들을 제어한다.
    • lock을 가진 스레드만이 해당 임계구역에 접근할 수있다.
    • 작업이 끝난 스레드는 Unlock을 사용하여 lock상태를 해제한다.
  • 단일 자원 보호에 최적화되어있으며, 사용이 간단하고 직관적이다. / 동기화 대상 자원(스레드)은 하나이다.
  • 특정 스레드가 소유권을 가지고 있는것을 확인할 수 있어 상태 관리가 명확하다.
std::mutex mtx; // 뮤텍스 선언
int sharedCounter = 0; // 공유 자원

void incrementCounter() {
    for (int i = 0; i < 5; ++i) {
        mtx.lock(); // 임계 영역 시작
        // ... 
        mtx.unlock(); // 임계 영역 종료
    }
}

 

 

세마포어 (Semaphore)

카운터(Counter)를 사용하여 공유하는 자원에 대한 동시 접근을 제한하는 방법입니다.

 

  • 사용 가능한 자원의 개수는 0개 이상의 정수(S)로 표현한다.
  • P(Wait) : 세마포어 값을 감소시키며, 값이 음수일 경우 해당 프로세스는 대기한다.
  • V(Signal) : 세마포어 값을 증가시키며, 대기중인 프로세스를 꺠울 수 있다.
  • S가 1일 경우 뮤텍스가 될 수 있다.
  • 변수값을 수정하는 연산은 원자성(Atomicity
  • 여러 자원에 대한 동시 접근을 제어 할  수 있다.
  • 설계가 복잡하며, 교착상태(Dead Lock)이 발생할 수 있다.
void accessResource() {
    sem.acquire(); // 세마포어 획득
    {
        // 임계 영역
        // ... 공유자원에 대한 접근 및 사용
        // 임계 영역
    }
    sem.release(); // 세마포어 해제
}

 

 

뮤텍스 VS 세마포어

  • 세마포어는 뮤텍스가 될 수 있지만, 뮤텍스는 세마포어가 될 수 없다.
    • 세마포어 S의 값이 1일 경우, 뮤텍스가 될 수 있다.
  • 세마포어는 소유가 아닌 대여 형태이며, 뮤텍스는 소유권을 가지고 있다.
    • 뮤텍스의 경우 뮤텍스를 소유하고 있는 스레드가 해당 뮤텍스를 해제(Unlock)할 수있다.
    • 세마포어의 경우 세마포어를 소유하지 않는 스레드가 세마포어를 해제할 수 있다.
  • 세마포어 : 자원의 수량을 제어한다.
  • 뮤텍스 : 자원의 단일 접근을 보장한다.

 

 

 

'OS , 네트워크' 카테고리의 다른 글

동기, 비동기, 블로킹, 논블로킹  (1) 2025.03.11
OSI 7계층  (0) 2025.03.10
TCP/IP 4계층  (0) 2025.02.06
TCP 와 UDP의 특징 및 차이점  (0) 2025.01.06

+ Recent posts