UDP 송수신 과정

|

##UDP 송∙수신 과정

수정 송신이 필요없는 데이터의 송신은 UDP가 효율적이다

  • DNS 서버에 IP 주소를 조회할 때, 동영상 및 음성 데이터를 송∙수신 할 때 UDP 프로토콜을 사용한다.

  • 데이터를 확실하고 효율적으로 전달하기 위해 복잡한 과정을 거치는 TCP 프로토콜[1]과는 달리 수신 확인이나 윈도우가 없어서 데이터 송∙수신 전에 제어정보를 주고받을 필요가 없고, 접속이나 연결 끊기 단계가 없다. 애플리케이션에서 송신 데이터를 받으면 여기에 UDP 헤더를 부가하고 이것을 IP에 의뢰하여 송신하기만 한다.

    수신도 간단하다. IP 헤더에 기록되어 있는 수신처 IP주소와 송신처 IP주소, 그리고 UDP 헤더에 기록되어 있는 수신처 포트번호와 송신처 포트번호라는 네 항목과 소켓에 기록된 정보를 결합하여 데이터를 건네줄 대상 애플리케이션을 판단하고 데이터를 건네준다. 오류가 발생하여 패킷이 없어져도 모른 체 한다. 패킷이 없어져서 회답이 돌아오지않으면 애플리케이션이 그 사실을 알아차리고 한 번더 송신하기만 한다. 복잡한 동작이 필요없어 애플리케이션에게 부담을 주지도 않는다.

[1] TCP 프로토콜 송∙수신 과정

  • 데이터를 보내고 수신확인 응답을 받는다. (정확성이 우선된다)
  • 어디까지 도착했는지 또는 오류가 발생하면 어디부터 다시 보내야하는 지 등 확인할 것이 많다.
  • 한 개의 패킷에 데이터가 모두 수용된다면 효율적인 구조이나, 대개 그렇지 않다.



ref 성공과 실패를 결정하는 1% 네트워크 원리

BOJ 17298번 오큰수

|

오큰수

package BOJ;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Stack;


/**
 * BOJ 17298
 * https://www.acmicpc.net/problem/17298
 */
public class RightBiggerNumber_17298 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine());
        int[] number = Arrays.stream(br.readLine().split("\\s")).mapToInt(Integer::parseInt).toArray();
        int[] answer = new int[n];

        solve(n, number, answer);
    }

    private static void solve(int n, int[] number, int[] answer) {
        Stack<Integer> stack = new Stack<>();
        stack.push(0);
        int num;
        for (int i = 1; i < n; i++ ){
            num = number[i];
            if(stack.isEmpty()){
                stack.push(i);
            }
            while(!stack.isEmpty() && number[stack.peek()] < num) {
                answer[stack.pop()] = number[i];
            }
            stack.push(i);
        }
        if(!stack.isEmpty()){
            int size = stack.size();
            for(int i=0; i < size; i++){
                answer[stack.pop()] = -1;
            }
        }
        print(answer);
    }

    private static void print(int[] answer) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < answer.length; i++)
            sb.append(answer[i] + " ");
        sb.delete(sb.length() - 1, sb.length());
        System.out.println(sb.toString());

    }
}

BOJ 10799번 쇠막대기

|

쇠막대기

package BOJ;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

/**
 * BOJ (10799)
 * https://www.acmicpc.net/problem/10799
 */
public class IronStick_10799 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        char[] brackets = br.readLine().toCharArray();
        Stack<Integer> leftBrackets = new Stack<>();
        List<Integer> razer = new ArrayList<>();
        int pieces = 0;

        for (int i = 0; i < brackets.length; i++) {

            switch (brackets[i]) {
                case '(':
                    leftBrackets.push(i);
                    break;

                case ')':
                    int left = leftBrackets.pop();
                    if (i - left == 1) { // 레이저인 경우
                        razer.add(i);
                    } else { // 막대인 경우
                        int razerOnStick = 0;
                        for (int razerIdx : razer) {
                            if (razerIdx < i && razerIdx > left) {
                                razerOnStick++;
                            }
                        }
                        if (razerOnStick > 0) {
                            pieces += razerOnStick + 1;
                        }
                    }
                    break;
            }
        }

        System.out.println(pieces);
    }
}

Queue,Deque

|

Queue(큐)

Queue

  • 한 쪽 끝에서만 자료를 넣고 다른 한쪽 끝에서만 뺄 수 있는 자료구조
  • 먼저 넣은 것이 가장 먼저 나오기 때문에 FIFO 라고도 한다
  • BFS에서 주로 사용한다

Queue 연산

  • push
    • 큐에 자료를 넣는 연산
  • pop
    • 큐에 자료를 빼는 연산
  • front
    • 큐의 가장 앞에 있는 자료를 보는 연산
  • back
    • 큐의 가장 뒤에 있는 자료를 보는 연산
  • empty
    • 큐가 비어있는지 확인하는 연산
  • size
    • 큐에 저장된 자료의 갯수를 알아보는 연산

Deque(덱)

Deque

  • 양 끝에서 자료를 넣고 양 끝에서 뺄 수 있는 자료구조

  • Double-ended queue의 약자이다

  • Deque을 구현하면 Stack, Queue를 구현했다고 볼 수 있다.

Deque 연산

  • push_front
    • 덱의 앞에 자료를 넣는 연산
  • push_back
    • 덱의 뒤에 자료를 넣는 연산
  • pop_front
    • 덱의 앞에서 자료를 빼는 연산
  • pop_back
    • 덱의 뒤에서 자료를 빼는 연산
  • front
    • 덱의 가장 앞에 있는 자료를 확인하는 연산
  • back
    • 덱의 가장 뒤에 있는 자료를 확인하는 연산

BOJ 1406번 에디터

|

에디터

package BOJ;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

/**
 * BOJ 1406
 * stack 이용하지 않으면 B,P 연산 시간복잡도 O(n)
 * https://www.acmicpc.net/problem/1406
 */
public class Editor_1406 {

    private static Stack<Character> left = new Stack<>();
    private static Stack<Character> right = new Stack<>();

    private static char[] input;

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        input = br.readLine().toCharArray();
        int cnt = Integer.parseInt(br.readLine());

        for (int i = 0; i < input.length; i++) {
            left.push(input[i]);
        }
        
        while(cnt-- > 0){
            String[] commandAndElement = br.readLine().split("\\s");
            doCommand(commandAndElement);
        }

        print();

    }

    private static void print() {
        StringBuilder sb = new StringBuilder();

        while(!left.isEmpty()){
            right.push(left.pop());
        }

        while(!right.isEmpty()){
            sb.append(right.pop());
        }

        System.out.println(sb.toString());
    }

    private static void doCommand(String[] commandAndElement){
        String command = commandAndElement[0];

        switch (command){
            case "L":
                if(!left.isEmpty()){
                    right.push(left.pop());
                }

                break;
            case "D":
                if(!right.isEmpty()){
                    left.push(right.pop());
                }
                break;
            case "B":
                if(!left.isEmpty())
                    left.pop();
                break;
            case "P":
                String element = commandAndElement[1];
                left.push(element.toCharArray()[0]);
                break;
        }
    }



}