<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>효라드</title>
        <link>https://velog.io/</link>
        <description>20210622 ~</description>
        <lastBuildDate>Thu, 15 Jul 2021 07:16:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>효라드</title>
            <url>https://images.velog.io/images/hyorard-b/profile/3fc1e1c3-936f-44fa-992d-9101fd9c8292/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 효라드. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyorard-b" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[HTTP]]></title>
            <link>https://velog.io/@hyorard-b/HTTP</link>
            <guid>https://velog.io/@hyorard-b/HTTP</guid>
            <pubDate>Thu, 15 Jul 2021 07:16:53 GMT</pubDate>
            <description><![CDATA[<h1 id="http-개요">HTTP 개요</h1>
<p>  HTTP는 애플리케이션 계층에서 데이터를 요청하는 클라이언트와 데이터를 제공하는 서버 간의 통신을 위한 프로토콜이다.</p>
<ol>
<li><p>HTTP를 통해 클라이언트와 서버는 통신 간에 개별적인 메시지로 통신한다. </p>
<p>클라이언트가 보내는 문서 요청을 request message, 서버가 보내는 문서 응답을 response message라고 한다. 클라이언트와 서버의 역할이 명확하게 구분되어 있음을 알 수 있다.</p>
</li>
<li><p>HTTP는 지속 연결로 통신량을 절약할 수 있다.</p>
<p>한 쪽이 연결을 종료하지 않으면 연결을 끊지 않는 <strong>지속 연결</strong>을 지원한다. 데이터 손실을 방지하기 위해 transport 계층의 TCP를 사용하지만, 다수의 요청을 할 경우에는 각 요청과 응답마다 연결과 연결 종료를 반복하게 되면 불필요한 통신이 늘어나기 때문에 HTTP1.1에서 지속 연결 개념을 도입하였다. 이에 더해, 요청에 대한 응답이 오지 않아도 다음 요청을 바로 보내도록 하는 <strong>파이프라인 개념</strong>도 도입하였다.
기본적인 TCP 제어는 HTTP 헤더 중 <code>connection</code> 필드를 통해 제어할 수 있다. 그러나 최근 HTTP2.0에서 <code>connection</code> 필드는 무시된다. 파이프라인 개념은 기존 소프트웨어와 최신 소프트웨어가 공존하는 상황에서 구현하기 어렵다는게 입증(어떻게?왜?)되었기 때문에, HTTP2.0의 프레임 안에서 활발하게 다중 요청을 통해 교체되고 있다<em>(HTTP 버전에 따른 차이는 뒤에 다시 정리해두었다.)</em>.</p>
</li>
<li><p>HTTP는 상태를 유지하지 않는(stateless) 프로토콜이다. </p>
<p>각각 개별적인 메시지로 통신하며 이전 상태를 관리하지 않는다. 데이터를 빠르고 확실하게 처리하기 위해 간단하게 설계되었기 때문이다. 이에 따라 request message당 새로운 response message가 생성된다. </p>
</li>
<li><p>HTTP는 간단하고, 확장하기 용이하다.</p>
<p>message의 헤더에 대한 클라이언트와 서버의 간단한 합의를 통해 <strong>기능을 쉽게 확장</strong>할 수 있다.</p>
</li>
<li><p>상태를 유지하기 위해 cookie를 사용한다.</p>
<p>cookie는 확장하기 쉬운 HTTP의 대표적 예시인 것 같다. 기존에 stateless였던 특징은 유지한 채, 새로운 헤더인 <code>Set-Cookie</code>와 <code>Cookie</code> 헤더에 대한 합의를 통해 cookie라는 이전 상태를 클라이언트에 보관하고, 새로운 요청에 cookie를 담아 보냄으로써 서버가 이전 상태를 확인할 수 있도록 하였다.</p>
</li>
<li><p>HTTP는 메소드를 통해서 다양한 요청을 할 수 있다.</p>
<p>GET, POST, PUT, HEAD, DELETE, OPTIONS, TRACE, CONNECT 등 여러 메소드를 통해 각각 다른 요청을 할 수 있다.</p>
</li>
</ol>
<h1 id="http-역사">HTTP 역사</h1>
<p>  HTTP 버전에 따른 차이를 알아보기 위해 HTTP0.9부터 HTTP2.0까지 버전별로 살펴보자.</p>
<h2 id="http09">HTTP0.9</h2>
<p>  HTTP0.9는 그 당시에 버전이 없었으므로 단지 HTTP라고 불릴 뿐이었으나, 다음 버전인 HTTP1.0과 구별하기 위해 현재 HTTP0.9라고 불린다. request, response message 모두 헤더가 없었기 때문에, 매우 단순하며 HTML 문서만으로 통신하였다.</p>
<p>  경로로 리소스를 요청하는 request message의 메소드는 GET이 유일했다.</p>
<pre><code>  GET /index.html</code></pre><p>  응답에는 상태나 오류 코드 없이 HTML 문서의 내용만이 들어가 있다.</p>
<pre><code>  &lt;HTML&gt;
    ...
  &lt;/HTML&gt;</code></pre><h2 id="http10">HTTP1.0</h2>
<p>  1991년부터 시도되었으며, 1996년 <a href="https://datatracker.ietf.org/doc/html/rfc1945">RFC 1945</a>에 공개되었지만 공식 표준은 아니었다고 한다.</p>
<p>  HTTP0.9와 다른 점은 바로 메시지 헤더의 출현이다. request, response message에 헤더가 포함되면서, </p>
<ol>
<li>HTML 문서 뿐만이 아닌 다른 형식의 문서도 주고 받을 수 있게 되었다. 
<code>Content-Type: text/html</code></li>
<li>응답 상태에 따라 클라이언트에서 다양한 처리를 할 수 있게 되었다.</li>
<li>특정 헤더에 대한 합의를 하게 되면, HTTP의 기능을 손쉽게 확장할 수 있게 되었다.</li>
</ol>
<h2 id="http11">HTTP1.1</h2>
<p>  HTTP1.0이 공개되고 얼마 지나지 않아 1997년 HTTP1.1이 <a href="https://datatracker.ietf.org/doc/html/rfc2068">RFC2068</a>에 첫 번째 HTTP 공식 표준으로 공개되었다. </p>
<p>   HTTP1.0과 HTTP1.1의 차이는 다음과 같다.</p>
<ol>
<li><p>지속 연결을 지원한다.</p>
<p>기존 개별 연결 시에는 TCP 연결, 연결 종료마다 반복되는 handshaking으로 인한 오버헤드가 존재하였다. 이를 해결하기 위해 HTTP1.0 시기에 문서에 없는 기능을 구현하여 지속 연결 개념을 사용하는 서버도 있었다. HTTP1.1에서는 어느 한 쪽이 연결을 종료하지 않으면 기존 연결을 재사용하여 오버헤드를 줄일 수 있게 하였다.
다만 사용이 완료되어 더 이상 통신할 필요가 없는 연결을 적절하게 종료하지 않는다면 리소스를 낭비할 수 있다는 단점이 있다.
다음 코드는 HTTP1.0으로 동작하는 경우에 대비하여 작성하기도 한다(fallback).
<code>Connection: Keep-Alive</code>
<code>Keep-Alive: timeout=5, max=1000</code></p>
</li>
</ol>
<ol start="2">
<li><p>파이프라인을 지원한다.</p>
<p>다수의 요청과 응답이 필요할 시 지속 연결보다 효율적인 것이 파이프라인이다. 파이프라인 개념은 요청을 보내고 이에 대한 응답을 기다리지 않고 다음 요청을 바로 보내는 것이다. 이로 인해 통신 지연율을 낮출 수 있으며, request 수가 많아질 수록 효과는 현저하게 나타난다.</p>
</li>
<li><p>청크 전송 코딩을 지원한다.</p>
<p>청크 전송 코딩이란 response 메시지의 바디 부분을 조금씩 나누어 보내어 클라이언트가 받아 조금씩 받아볼 수 있게(표시할 수 있게)하는 것이다. 기존에는 요청했던 리소스의 바디가 모두 전송되지 않으면 표시할 수 없었다.
<code>Transfer-Encoding: chunked</code></p>
</li>
<li><p>언어/인코딩을 포함한 컨텐츠에 대한 합의를 함으로써 상황에 더 적절한 컨텐츠를 주고받을 수 있게 되었을 뿐 아니라 전송 효율도 높였다.</p>
<p><code>Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</code>
<code>Accept-Language: en-US,en;q=0.5</code> 
<code>Accept-Encoding: gzip, deflate, br</code></p>
</li>
</ol>
<h2 id="http20">HTTP2.0</h2>
<p>  현대에 이르러 웹 상에서는 기존 보다 더 많은 요청에 의해 더 많은 데이터를 주고 받게 되었고, HTTP1.1은 이러한 상황을 감당하기에는 많은 오버헤드와 복잡성을 가지고 있었다. 대표적으로 파이프라인은 기존 소프트웨어와 최신 소프트웨어가 공존하는 기존의 네트워크에서 구현하기 어려웠다.</p>
<p>  이러한 상황에서 구글은 2010년 SPDY 프로토콜 실험을 통해 응답성 증가 능력(?)을 입증하고 전송된 데이터 중복에 관한 문제(?)를 해결하며 HTTP2.0의 기반을 다졌다.</p>
<p>  HTTP1.1과 HTTP2.0의 차이는 다음과 같다.</p>
<ol>
<li><p>메시지가 이진 포맷으로 인코딩된다.</p>
<p>기존 plain text와 달리, 메시지가 이진 포맷으로 인코딩되었고, 메시지의 전체 구성도 바뀌었다. 기존 헤더는 Headers frame으로, 바디는 DATA frame으로 불린다. 이 두 프레임이 합쳐져 하나의 message를 구성한다. </p>
<p>오버헤드와 에러가 줄어들며, 네트워크 자원을 최적화할 수 있고, HTTP1.x 버전이 가지고 있던 응답 분할과 같은 평문적 보안 취약점을 제거할 수 있게 되었다.</p>
<blockquote>
<p>응답 분할 공격이란 request의 파라미터가 response의 헤더로 다     시 전달되는 경우 파라미터 내에 CR 또는 LF가 존재하면 HTTP 응답이 분리되는데 이에 코드를 주입하여 XSS 및 캐시를 훼손하는 것을 말한다.</p>
</blockquote>
</li>
<li><p>동일한 연결에서 병렬 요청이 가능하다.</p>
<p>HTTP2.0에서는 stream이라는 개념을 사용하는데, stream은 구성된 하나의 연결 내에서 하나 이상의 메시지를 양방향으로 전송할 수 있다.</p>
<p>기존에는 여러 개의 파일을 요청했을 때, 앞의 파일이 전송이 늦어지면 뒤 쪽 파일들이 모두 밀려 전체 전송 시간이 지연되었다<em>(HOL Blocking. Head Of Line Blocking)</em>. HTTP1.1에서는 파이프라인을 도입하여 해결하려 했지만, 도입에 문제가 있었다.</p>
<p>HTTP2.0은 stream을 통해 여러 파일을 병렬 요청하고, 병렬적으로 응답받을 수 있게 되어 페이지 로딩 시간을 단축할 수 있게 하였다.</p>
</li>
<li><p>중복된 헤더를 압축한다.</p>
<p>HTTP2.0은 HPACK이라는 압축 방식을 사용하여 헤더를 압축하여 전송한다. 클라이언트와 서버는 이전에 전송한 message를 남겨놓았다가, 새로운 message를 전송할 때 이전의 압축된 message를 보고 반복되는 부분을 쉽고 안전하게 압축한다.</p>
</li>
<li><p>필요하게 될 파일을 미리 전송한다.</p>
<p>서버는 클라이언트가 지금 요청하지 않았지만 요청하게 될 데이터를 보낼 수 있게 되었다. 예를 들어, 클라이언트가 X 리소스를 요청하였고, Y 리소스가 이와 연관되어 있다면, 서버는 클라이언트가 Y 리소스를 요청할 때까지 기다리지 않고 Y 리소스를 X와 함께 &#39;푸시&#39;한다. 이를 Server Push라고 부른다.
클라이언트는 푸시된 리소스를 다른 페이지에 사용 가능하며, 서버가 푸시한 리소스에 우선 순위를 둘 수 있고, 클라이언트가 푸시된 리소스를 거절하거나 서버 푸시 전체를 비활성화할 수 있다.</p>
</li>
</ol>
<h2 id="파이프라인-개념은-기존-소프트웨어와-최신-소프트웨어가-공존하는-상황에서-구현하기-어렵다는게-입증어떻게왜">파이프라인 개념은 기존 소프트웨어와 최신 소프트웨어가 공존하는 상황에서 구현하기 어렵다는게 입증(어떻게?왜?)</h2>
<p>출처
<a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Overview">MDN - HTTP 개요</a>
<a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP">MDN - HTTP 진화</a>
<a href="https://factoryhr.medium.com/http-2-the-difference-between-http-1-1-benefits-and-how-to-use-it-38094fa0e95b">HTTP/2: the difference between HTTP/1.1, benefits and how to use it</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TCP 헤더]]></title>
            <link>https://velog.io/@hyorard-b/TCP-%ED%97%A4%EB%8D%94</link>
            <guid>https://velog.io/@hyorard-b/TCP-%ED%97%A4%EB%8D%94</guid>
            <pubDate>Mon, 12 Jul 2021 08:15:13 GMT</pubDate>
            <description><![CDATA[<h1 id="tcp-헤더">TCP 헤더</h1>
<p>TCP 세그먼트는 옵션 필드가 없는 최소 20바이트에서 최대 60바이트 크기의 헤더 필드를 사용하여 데이터를 나타낸다.</p>
<p><img src="https://images.velog.io/images/hyorard-b/post/e55457da-729e-4285-9002-b066aa11242b/tcp%20header.PNG" alt="TCP 헤더">
출처 - <a href="http://www.ktword.co.kr/abbr_view.php?nav=&amp;m_temp1=1889&amp;id=1103">http://www.ktword.co.kr/abbr_view.php?nav=&amp;m_temp1=1889&amp;id=1103</a></p>
<h2 id="tcp-헤더-필드">TCP 헤더 필드</h2>
<ol>
<li><p>포트주소 (발신지 16비트 / 목적지 16비트)
어느 어플리케이션에 해당하는 데이터인지 알아야 하기 때문에, 포트 주소를 통해 판단한다. TCP/UDP 포스팅에서도 설명했지만, 발신지와 목적지 포트 주소 모두 필요하다. 다른 어플리케이션이 같은 곳에 요청을 했을 경우 발신지의 포트 주소를 통해 판단하여야 하고, 같은 IP 주소에 각각 다른 어플리케이션에 요청을 했을 경우 목적지의 포트 주소를 통해 판단할 수 있기 때문이다.</p>
</li>
<li><p>Sequence Number (32비트)
보내는 데이터의 순서를 나타내는 필드이다. 데이터 조각들은 보내는 순서대로 도착하지 않는다. 이를 위해, 언제 도착하던 간에 순서를 맞출 수 있도록 데이터의 순서를 TCP 헤더에 표기한다. 
첫 데이터 전송 시에 32비트 안에서 무작위 난수를 생성하여 초기화하는데, 이 수를 ISN(Initial Sequence Number)라고 한다. Sequence Number는 ISN에서 전송하는 데이터 1바이트 당 1씩 증가시킨다. </p>
</li>
<li><p>Acknowledge Number (32비트)
다음에 받아야 할 데이터의 순서를 나타내는 필드이다. 자신이 어디까지 데이터를 받았으니, 여기부터 데이터를 보내달라는 것을 알리기 위한 용도를 가진다.
마지막으로 수신한 데이터의 Sequence Number가 <code>...1101</code>이라면 이에 대한 응답 또는 요청으로 Acknowledge Number는 <code>...1110</code>이 되는 것이다.</p>
</li>
<li><p>Header Length (4비트)
지금 보내는 데이터에서 헤더가 차지하는 영역이 어디까지인 지를 나타내는 필드이다. 즉, 헤더를 제외하고 실제 데이터가 시작되는 지점을 알려주는 용도를 가진다.
단위는 비트나 바이트가 아닌 워드로, <code>0000</code> ~ <code>1111</code>까지 15워드(60바이트)까지 나타낼 수 있다. 옵션을 제외한 TCP 헤더의 크기는 20바이트이므로, 충분히 나타낼 수 있다. </p>
</li>
<li><p>Reserved (3비트)</p>
</li>
<li><p>Flags (9비트)</p>
<ul>
<li>NS, ECW, CWR 
새로 추가된 비트로, 네트워크의 명시적 혼잡 통보를 위한 비트이다.</li>
<li>URG
Urgent Pointer 필드가 채워져 있는지를 나타낸다.</li>
<li>ACK
Acknowledge Number 필드가 채워져 있는지를 나타낸다.</li>
<li>PSH
필드가 채워져 있다면, 수신 측은 받은 데이터를 바로 애플리케이션 계층에 전달하고, 그렇지 않다면 버퍼가 채워질 때까지 기다린다.</li>
<li>RST
이미 연결이 확립되어 있는 ESTABLISHED 상태인 상대방에게 강제 RESET 요청을 하는 필드이다.</li>
<li>SYN
상대방과 초기 연결 중, handshaking을 위한 번호이다.</li>
<li>FIN
상대방과 연결 종료 중, handshaking을 위한 번호이다.</li>
</ul>
</li>
<li><p>Window Size (16비트)
한 번에 전송할 수 있는 데이터의 양을 나타낸다. 단위는 KB이다.</p>
</li>
<li><p>Checksum (16비트)
데이터를 보낼 때, 보내는 데이터를 16비트 씩 쪼개어 모두 더하며, 캐리는 맨 밑 비트부터 더하게 된다. 모두 더했다면 비트를 반전시켜 필드에 담는다.
수신 측은 보낼 때와 같이 16비트 씩 쪼개어 모두 더한 다음, Checksum의 데이터와 더하는데 모든 비트가 1이 아니라면, 데이터가 깨져 신뢰성이 없다고 판단하게 되는 최소한의 오류 검증 필드이다.</p>
</li>
<li><p>Urgent Pointer
플래그 비트 중 URG가 1이라면, 이 필드에 해당하는 데이터부터 먼저 처리하게 한다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[DNS에 대해]]></title>
            <link>https://velog.io/@hyorard-b/DNS%EC%97%90-%EB%8C%80%ED%95%B4</link>
            <guid>https://velog.io/@hyorard-b/DNS%EC%97%90-%EB%8C%80%ED%95%B4</guid>
            <pubDate>Mon, 12 Jul 2021 06:23:33 GMT</pubDate>
            <description><![CDATA[<h1 id="dns란">DNS란?</h1>
<p>Domain Name Service의 줄임이다. IPv4의 경우 xxx.xxx.xxx.xxx로 12자리 숫자로 이루어진 주소로 네트워크 호스트를 구분하는데, 각 호스트들의 주소를 일일이 기억하기 어렵기 때문에 이 주소를 <a href="http://www.naver.com">www.naver.com</a> 등의 영문으로 입력하면 해당 주소로 변환해주는 서비스이다. </p>
<h2 id="dns-계층">DNS 계층</h2>
<p><img src="https://images.velog.io/images/hyorard-b/post/a4097c1d-5159-4a51-88f3-8b30063802e1/DNS.PNG" alt="DNS 계층">
DNS는 위 그림과 같이 계층적으로 관리된다. 트래픽이 많으며, 장애 발생시 대처도 용이하고, 먼 거리에서 통신하는 경우가 많기 때문에 중앙 집중형이 아니라 DNS 서버들은 분산형으로 관리된다.</p>
<h2 id="dns-해석">DNS 해석</h2>
<p><img src="https://images.velog.io/images/hyorard-b/post/7eb7c605-4ff2-49a8-96ea-51f248d59aca/DNS%20translate.PNG" alt="DNS 해석 과정">
DNS는 위 그림과 같이 동작한다. 예를 들어 <a href="http://www.youtube.com%EC%9D%84">www.youtube.com을</a> 브라우저 주소창에 쳤다고 가정하자. </p>
<ol>
<li>브라우저는 운영체제에 요청하고, 운영체제는 IP주소를 매핑하는 파일인 <code>hosts</code> 파일에 캐싱되어 있는지 확인한다. 있다면 해당 주소로 요청하고 없다면 Local DNS 서버에 주소를 요청한다.</li>
<li>Local DNS 서버에 주소가 캐싱되어 있다면, 해당 주소를 응답한다. 캐싱되어 있지 않다면 ROOT DNS 서버에 요청한다.</li>
</ol>
<p>여기서 부터 질의 방식이 나뉘게 된다.</p>
<h3 id="반복적-질의">반복적 질의</h3>
<ol start="3">
<li>ROOT DNS에 캐싱되어 있다면, 응답하고 그렇지 않다면 .com DNS 서버의 주소를 응답한다.</li>
<li>Local DNS는 응답받은 .com DNS에 주소를 요청한다.</li>
<li>.com DNS에 캐싱되어 있다면, 응답하고 그렇지 않다면 youtube.com 서버의 주소를 응답한다.</li>
<li>Local DNS는 응답받은 youtube.com DNS에 <a href="http://www.youtube.com">www.youtube.com</a> 주소를 요청한다.</li>
</ol>
<h3 id="재귀적-질의">재귀적 질의</h3>
<ol start="3">
<li>ROOT DNS에 캐싱되어 있다면, 응답하고 그렇지 않다면 .com DNS 서버에 요청한다.</li>
<li>.com DNS 서버에 캐싱되어 있다면, 응답하고 그렇지 않다면 youtube.com DNS 서버에 요청한다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[TCP와 UDP 프로토콜]]></title>
            <link>https://velog.io/@hyorard-b/TCP%EC%99%80-UDP-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</link>
            <guid>https://velog.io/@hyorard-b/TCP%EC%99%80-UDP-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C</guid>
            <pubDate>Fri, 25 Jun 2021 08:57:15 GMT</pubDate>
            <description><![CDATA[<h1 id="tcp와-udp">TCP와 UDP?</h1>
<p>  전송(transport) 계층에서 데이터 전송을 위해 사용하는 2가지 프로토콜입니다.</p>
<h1 id="tcp-프로토콜">TCP 프로토콜</h1>
<p>  신뢰성 있는 바이트 스트림 서비스를 제공합니다. 신뢰성이 있다는 것은 데이터가 손실 없이 제시간에 도착하며, 도착하지 않았을 경우 대처할 방안이 있다는 것을 의미합니다. 하나의 데이터를 TCP 세그먼트라고 불리는 작은 데이터 조각으로 나누어 전송하고, 정확하게 도착했는지 확인하는 역할을 담당합니다.</p>
<h2 id="연결-지향형">연결 지향형</h2>
<p>  서버와 클라이언트를 연결시켜 놓고 데이터를 주고 받습니다. 연결이 끝나기 전에는 몇 번이든 데이터를 주고 받을 수 있습니다.
  그러나, 각 연결이 독립적이기 때문에 연결이 끊어지고 나면 전 연결에 대한 정보가 사라진다는 단점이 있습니다. 예를 들어, 이메일을 전송하고 나서 연결이 끊기고 나면, 전 이메일에 대한 정보를 얻기 위해서 다시 연결을 해야 합니다. 최근에는 지속 HTTP 연결을 사용하기 때문에 이러한 문제점이 없어졌다고 할 수 있습니다.
  만약, 데이터의 양이 적어 연결을 하고 끊는 시간보다 전송 시간이 적다면, 비효율적인 연결이 되게 됩니다. </p>
<h3 id="tcp의-디멀티플렉싱">TCP의 디멀티플렉싱</h3>
<p>  받은 데이터의 헤더 정보(IP 주소, 포트 번호 등)를 분석하여 해당 프로세스에 디멀티플렉싱하게 됩니다.
  연결이 되어 있기 때문에, IP 주소와 포트 번호를 안 붙여도 될 것 같습니다. 그러나, 헤더 정보에 포함하는 이유가 있습니다. 같은 포트 번호를 가진 다른 센더가 보내는 경우 IP 주소가 없다면 식별할 수 없습니다. 같은 식으로 같은 센더의 다른 프로세스가 보내는 경우 포트 번호가 없다면 프로세스를 식별할 수 없습니다.</p>
<h2 id="신뢰성">신뢰성</h2>
<p>  TCP 프로토콜을 사용하게 된다면, 애플리케이션 계층에서는 신뢰성에 대해 상관할 필요가 없게 됩니다. 네트워크 계층에서 패킷 드롭 등으로 인해 데이터가 손실된다하여도 재전송을 요청하게 됩니다.</p>
<h3 id="신뢰성을-위한-2-way-3-way-4-way-handshaking">신뢰성을 위한 2-way, 3-way, 4-way handshaking</h3>
<p> handshaking은 프로세스 간 신뢰성을 보장하며 데이터를 주고 받기 위한 TCP의 세션 연결 방식입니다. 데이터를 주고 받기 전에 서버와 클라이언트 간에 연결을 하고 잘 되었는지 확인하는 것입니다. </p>
<h4 id="2-way-handshaking">2-way handshaking</h4>
<p><img src="https://images.velog.io/images/hyorard-b/post/65366c9f-2fe8-43dd-af37-d4590197573d/2way.PNG" alt="2way handshaking"></p>
<ol>
<li>클라이언트가 서버에 SYN 비트를 전송합니다.</li>
<li>SYN 비트를 받은 서버가 클라이언트에 ACK 비트를 전송합니다. <strong>1(서버 쪽 연결 확립)</strong></li>
<li>클라이언트가 ACK 비트를 받습니다. <strong>2(클라이언트 쪽 연결 확립)</strong></li>
</ol>
<hr>
<p>  얼핏 보기에 문제가 없어 보이지만, 2-way handshaking은 서버와 클라이언트가 서로의 상황을 모른다는 점에서 문제가 존재합니다. 다음 시나리오는 문제가 존재합니다.</p>
<p>  <img src="https://images.velog.io/images/hyorard-b/post/04d380b4-e5e0-4513-9c41-cbbd9e96d78a/2wayProblem.PNG" alt="2way handshaking problem"></p>
<ol>
<li><p>클라이언트가 서버에 SYN 비트를 전송합니다.</p>
</li>
<li><p>SYN 비트를 받은 서버가 클라이언트에 ACK 비트를 전송합니다. <strong>(서버 쪽 연결 확립)</strong></p>
</li>
<li><p>클라이언트 쪽에서 timeout이 발생하여, SYN 비트를 재전송합니다.</p>
</li>
<li><p>서버가 보낸 ACK 비트가 클라이언트에 도착합니다.</p>
<p>서버가 ACK 비트를 보내기 전에 클라이언트 쪽에서 timeout이 발생해 SYN 비트를 재전송하게 되고, 그 다음 서버의 ACK 비트가 도착하게 되는 시나리오는 서버만이 클라이언트와 연결된 지 아는, 클라이언트가 존재하지 않는 반만 연결된 세션이 열리게 됩니다.</p>
</li>
</ol>
<h4 id="3-way-handshaking">3-way handshaking</h4>
<p><img src="https://images.velog.io/images/hyorard-b/post/c29f590a-5412-42cd-a31b-56e0c70c8cbb/3way.PNG" alt="3way handshaking"></p>
<p>  이에 비해, 서로가 데이터를 보낼 때 연결된 것을 보장하고 서로 인지하고 있는 방식이 3-way handshaking입니다. 앞의 클라이언트가 연결이 확립되었는지 서버가 모르는 것을 방지하기 위해 클라이언트가 연결이 확립되었다는 것을 서버에게 알려주는 단계가 하나 추가됩니다.</p>
<ol>
<li>클라이언트가 서버에 SYN 비트를 보내고 SYN-SENT 상태가 됩니다.<strong>(1)</strong></li>
<li>서버가 SYN 비트를 받아 SYN-ACK 비트를 보내고 SYN-RECEIVED 상태가 됩니다.<strong>(2)</strong></li>
<li>클라이언트가 SYN-ACK 비트를 받고 <strong>ESTABLISHED</strong> 상태가 되어 ACK 비트를 보냅니다.<strong>(3)</strong></li>
<li>서버가 ACK 비트를 받고 <strong>ESTABLISHED</strong> 상태가 됩니다.</li>
</ol>
<h4 id="4-way-handshaking">4-way handshaking</h4>
<p><img src="https://images.velog.io/images/hyorard-b/post/f8975fe7-fce5-4056-b3a3-b897b7e57118/4way.PNG" alt="4way handshaking"></p>
<p>  4-way handshaking은 데이터 송수신 전 세션 연결 단계가 아닌 세션 종료를 위한 방식입니다.</p>
<ol>
<li><p>클라이언트가 서버에 FIN 비트를 보냅니다.<strong>(1)</strong></p>
</li>
<li><p>FIN 비트를 받은 서버가 클라이언트에 ACK 비트를 보내고 <strong>CLOSE_WAIT</strong> 상태가 됩니다.<strong>(2)</strong></p>
</li>
<li><p>ACK 비트를 받은 클라이언트는 <strong>FIN_WAIT</strong> 상태가 됩니다.</p>
</li>
<li><p>일정 시간 후 서버는 클라이언트에 FIN 비트를 보내고 <strong>LAST_ACK</strong> 상태가 됩니다.<strong>(3)</strong></p>
</li>
<li><p>FIN 비트를 받은 클라이언트는 ACK 비트를 보내고 <strong>TIME_WAIT</strong> 상태가 됩니다.<strong>(4)</strong></p>
</li>
<li><p>ACK 비트를 받은 서버는 연결을 종료하고 <strong>CLOSED</strong> 상태가 됩니다.</p>
<p>4단계에서 클라이언트는 <strong>TIME_WAIT</strong> 상태로 세그먼트의 lifetime*2 (디폴트는 240초) 시간 동안 대기하게 되는데, 이는 서버가 보낸 FIN 비트가 FIN 비트 전의 데이터보다 빨리 도착하게 되는 경우에 늦게 도착하는 데이터를 기다리게 하는 과정입니다.</p>
<h2 id="흐름-제어">흐름 제어</h2>
<p>센더와 리시버의 데이터 처리 속도 차이를 해결하기 위한 방법입니다.
리시버 측이 센더 측 보다 처리 속도가 느리다면, 패킷 드롭이 발생하게 되고 불필요한 데이터 송수신을 하게 됩니다. 따라서, 리시버 측에 버퍼를 두고, 버퍼의 상태를 센더에게 알려주게 됩니다. 
센더 측의 데이터 처리 속도가 느리다면, 애플리케이션 계층은 계속 데이터를 보내고 있기 때문에, 센더의 트랜스포트 계층에서 데이터 드롭이 일어날 수 있습니다. 따라서 센더 측에도 버퍼를 두어 관리하게 합니다.</p>
</li>
</ol>
<h3 id="1-stop-and-wait-방식">1. Stop and Wait 방식</h3>
<p>  센더 측이 데이터를 하나 보내고, 받았다는 응답이 오면 다음 데이터를 보내는 방식입니다.</p>
<h3 id="2-sliding-window-방식">2. Sliding Window 방식</h3>
<p>  센더가 리시버의 버퍼(윈도우)에 맞춰 데이터를 보내는 방식입니다. 센더는 윈도우만큼의 데이터를 보내고, 리시버가 어디까지 받았다고 신호를 하면 받은 만큼 윈도우를 옮겨 보내는 방식입니다.</p>
<h2 id="혼잡도-제어">혼잡도 제어</h2>
<p>  회선을 많이 사용하는 특정 회선의 요청을 제한하거나 모든 회선의 요청을 제한하여, 회선 혼잡도를 제어합니다.</p>
<h3 id="1-끝점간-제어">1. 끝점간 제어</h3>
<p>  호스트 사이의 라우터들이 혼잡도를 제어하는 것이 아닌, 네트워크 사정에 따라 호스트들이 제어하는 것을 말합니다. AIMD (Additive Increase / Multicative Decrease) 방식은 1부터 시작하여 window 크기를 1씩 증가시키며 보내고, 패킷 전송이 실패하게 되면 window 크기를 반으로 줄입니다. 
  또 다른 방식은 1부터 시작하여 곱으로 올리고, 3개의 중복된 ACK가 도착하면 TCP Reno는 window 크기를 반으로 줄이고, TCP Tahoe는 window 크기를 1로 줄입니다. 이 밖에도 많은 방식이 있습니다.</p>
<h3 id="2-네트워크-지원-제어">2. 네트워크 지원 제어</h3>
<p>  일반적인 제어 방식이 아닙니다. 라우터들이 호스트들에게 네트워크 상황을 제공합니다.</p>
<h2 id="순차-전송">순차 전송</h2>
<p>  UDP와 달리 데이터를 순차적으로 전송합니다.</p>
<hr>
<h1 id="udp-프로토콜">UDP 프로토콜</h1>
<p>  TCP와 달리 비연결형 프로토콜으로, 속도가 빠르지만 데이터의 신뢰성을 보장하지 않는 프로토콜입니다. 
  데이터의 순서를 보장하는 TCP와 달리 데이터의 순서를 보장하지 않습니다. 데이터가 유실된다해도 재전송을 요청하지 않고, handshaking을 하지 않습니다. 
  최소한의 오류를 검출하기 위해 checksum 방식을 사용합니다. </p>
<h2 id="udp의-checksum">UDP의 checksum</h2>
<p>  전송 과정의 최소한의 오류를 검출하기 위한 방식으로 보내는 쪽에서 정해진 방식에 따라 checksum을 각 독립적인 세그먼트의 헤더에 넣습니다. 받는 쪽에서는 checksum이 맞는지 확인하여 틀리면 버립니다.
  그러나, checksum이 맞다고 하여 데이터 안쪽이 손상된 확률도 있기 때문에 데이터의 신뢰성을 보장하고 싶다면 TCP방식을 사용하거나 응용 계층에서 구현하여 추가하여야 합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OSI 7 계층]]></title>
            <link>https://velog.io/@hyorard-b/OSI-7-%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@hyorard-b/OSI-7-%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Tue, 22 Jun 2021 07:03:38 GMT</pubDate>
            <description><![CDATA[<h2 id="프로토콜">프로토콜?</h2>
<p>상호 통신을 위해서는 같은 방법을 사용해서 통신을 해야 합니다. 그러나, 통신을 하는 서버나 클라이언트는 각기 다른 하드웨어와 운영체제를 사용하고 있기 때문에 통신을 위한 모든 요소에 규칙이 필요하게 되는데 이러한 통신에 필요한 규칙들을 프로토콜이라 합니다.</p>
<h2 id="tcpip">TCP/IP?</h2>
<p>케이블 규격, IP 주소 지정 방법, 서버 및 클라이언트를 찾기 위한 방법과 통신하기 위한 방법, 순서 등과 같이 인터넷과 관련된 프로토콜을 모은 것을 TCP/IP라고 합니다. </p>
<h2 id="osi-7-계층">OSI 7 계층?</h2>
<p>하나의 프로토콜로 인터넷을 관리하게 되면, 유지보수가 어렵게 됩니다. 한 부분의 사양이 변경된다면 전체의 사양을 변경해야 하기 때문입니다. </p>
<p>그리고 설계 또한 어렵습니다. 서비스를 개발할 때, 전체 단계를 모두 고려해야 하기 때문에 서버 또는 클라이언트가 어떤 방식으로 도착지를 찾을 지, 어떤 방법, 순서로 도착할 지, 확실하게 메시지가 전달되고 있는지에 대해 고려하여야 합니다. </p>
<p>이에 따라 응용 - 표현 - 세션 - 전달 - 네트워크 - 링크 - 물리, 7단계로 프로토콜을 계층화한 것이 OSI 7 계층입니다.</p>
<p><img src="https://images.velog.io/images/hyorard-b/post/33c70755-06a1-4b8a-b20e-85718a60d30c/layer.png" alt="OSI 7 계층"></p>
<h3 id="1-응용-application-계층">1. 응용 (application) 계층</h3>
<p>  데이터 형식은 message로, 가장 상단에 위치하여 네트워크를 이용하는 프로그램입니다. HTTP 뿐 아니라, FTP, DNS 등의 공통 애플리케이션이 준비되어 있습니다.</p>
<h3 id="2-표현-presentation-계층">2. 표현 (presentation) 계층</h3>
<p>  애플리케이션을 통해 데이터를 주고 받는데 그 데이터가 암호화,압축이 필요하다면 프레젠테이션 계층이 수행합니다. 이로 인해 응용 계층에서의 데이터 형식 차이를 다루는 부담을 덜어줍니다.</p>
<h3 id="3-세션-session-계층">3. 세션 (session) 계층</h3>
<p>  TCP/IP 세션을 없애고 만드는 역할을 한다.</p>
<h3 id="4-전송-transport-계층">4. 전송 (transport) 계층</h3>
<p>  프로세스 간 데이터를 구별하여, 해당 프로세스로 데이터를 전송하는 역할을 합니다. 응용 계층의 message 앞에 데이터를 붙여 datagram을 만듭니다. TCP와 UDP 2가지 프로토콜이 있습니다. </p>
<p>TCP와 UDP 프로토콜은 다시 다뤄보아야 하겠다..</p>
<h3 id="5-네트워크-network-계층">5. 네트워크 (network) 계층</h3>
<p>  대표적으로 라우터가 있습니다. 링크 계층을 통해 router로 전송되었다면, link 계층에서 붙인 데이터를 떼내어 packet의 정보를 보고, 데이터를 전송하게 됩니다. 
  라우터 큐가 꽉 차서 더 이상 데이터를 받을 수 없게 된다면, 패킷 드롭이 발생하게 됩니다. 그러면 일반적으로 호스트에게 재전송 요청을 하지 않습니다. 그러면 클라이언트가 일정 시간이 지나 데이터가 오지 않음을 인지하였을 때 재전송 요청을 하게 되는데, 이에 따라 상당한 네트워크 지연이 발생하게 됩니다.  </p>
<h3 id="6-링크-link-계층">6. 링크 (link) 계층</h3>
<p>  네트워크에 접속하는 하드웨어적인 면을 다룹니다. 대표적으로 스위치가 있습니다. 물리 계층의 데이터를 인접 기기로 전송한다는 점에서 네트워크 계층과 차이가 있습니다. 
  네트워크 계층의 packet 앞에 데이터를 붙여 frame을 만듭니다. frame은 물리 계층을 통해 인접 기기로 전송되다가 네트워크 계층의 router로 향하게 됩니다.</p>
<h3 id="7-물리-physical-계층">7. 물리 (physical) 계층</h3>
<p>  데이터 형식은 bit로, 대표적으로 케이블, 허브 등이 있습니다. 전기 신호만을 전송하는 역할을 합니다.</p>
<h2 id="캡슐화">캡슐화?</h2>
<p>각 계층을 거칠 때는 해당 계층에 필요한 정보를 추가하고, 수신측에서는 각 계층에서 사용한 헤더를 삭제하는데 이렇게 정보를 감싸는 것을 캡슐화라고 합니다.</p>
<p>응용 계층 <em>(+HTTP 데이터)</em> -&gt; <strong>HTTP 메시지</strong>
-&gt; 전달 계층 <em>(+TCP 헤더)</em> -&gt; <strong>TCP 세그먼트</strong>
-&gt; 네트워크 계층 <em>(+IP 헤더)</em> -&gt; <strong>IP 패킷</strong>
-&gt; 링크 계층 <em>(+Ethernet 헤더)</em> -&gt; <strong>네트워크 프레임</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[style-loader와 MiniCssExtractPlugin은 각각 언제 사용해야 할까?]]></title>
            <link>https://velog.io/@hyorard-b/style-loaderMiniCssExtractPlugin</link>
            <guid>https://velog.io/@hyorard-b/style-loaderMiniCssExtractPlugin</guid>
            <pubDate>Tue, 09 Mar 2021 10:23:00 GMT</pubDate>
            <description><![CDATA[<h1 id="두-플러그인의-차이">두 플러그인의 차이</h1>
<p>웹팩을 사용하게 되면서 style-loader는 문서의 스타일 태그 안에 스타일링을, MiniCssExtractPlugin은 별도의 css 파일로 번들링한다는 차이점은 인지하고 있었다.</p>
<p>그런데 특정 프로젝트에 최적화하려면 어떤 플러그인을 써야 되는 지에 대해 의문점이 들었다🤔🤔🤔</p>
<h2 id="스타일-태그">스타일 태그</h2>
<p>스타일 태그로 스타일링을 주입하게 되면, 따로 CSS 파일을 요청하지 않기 때문에, 페이지 랜딩 속도가 비교적 빠르다.</p>
<p>따라서, 대용량 트래픽을 감당해야 하거나 네이버, 다음과 같이 페이지 랜딩 속도가 빨라야 하는 검색 포털 사이트에 적합하다.</p>
<p>그러나, 사용하지 않는 인라인 스타일들도 같이 받는다는 점에서 비효율적일 수 있다.</p>
<hr>
<h2 id="css-파일">CSS 파일</h2>
<p>css 파일로 스타일링 하게 되면, 문서가 css 파일을 요청하게 되고, 이를 불러오기 위해 통신이 다시 일어나게 된다.</p>
<p>따라서, 랜딩 속도가 느려지게 된다. CSSOM 트리가 그 만큼 늦게 그려지기 때문이겠지🙄🙄</p>
<p>그러나, 해당 문서가 요청하는 파일(즉 스타일링)만 가져온다는 점은 스타일 태그에 비해 좋은 것 같다.</p>
<hr>
<h2 id="내가-생각했을-때-베스트">내가 생각했을 때 베스트</h2>
<p>만약 SPA라면, style-loader가 베스트일 것 같다. 왜냐하면, 모든 스타일들을 사용할 가능성이 많기 때문이다.</p>
<p>그러나, 특정 페이지만이 사용하는 css 파일의 용량이 클 경우라면, MiniCssExtractPlugin이 베스트일 것이다!</p>
<hr>
<p><a href="https://webpack.js.org/loaders/style-loader/#root">style-loader 웹팩 문서</a>
<a href="https://webpack.js.org/plugins/mini-css-extract-plugin/">MiniCssExtractPlugin 웹팩 문서</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[마우스 포커스와 키보드 포커스를 구분하는 방법]]></title>
            <link>https://velog.io/@hyorard-b/focus-visible</link>
            <guid>https://velog.io/@hyorard-b/focus-visible</guid>
            <pubDate>Tue, 09 Mar 2021 09:21:43 GMT</pubDate>
            <description><![CDATA[<p>리액트 수업 중에 강사님이 이 코드에 대해 알아봐라 하셔서 적어놨다가 찾아볼 시간이 생겨 올리는 글이자 첫 velog 포스팅.</p>
<h1 id="focus-visible">:focus-visible</h1>
<pre><code class="language-css">.button:focus {
    outline: none;
    box-shadow: 0 0 0 4px rgba(147, 153, 210, 0.56);
}
.button:focus:not(:focus-visible) {
    box-shadow: none;
}</code></pre>
<h2 id="outlinenone">outline:none</h2>
<p>버튼 요소에 포커스가 갔을 경우 outline에 대한 스타일링을 하지 않으면 다음과 같이 렌더링된다.</p>
<ul>
<li><p>스타일링을 하지 않았거나 reset.css를 적용했을 경우
<img src="https://images.velog.io/images/hyorard-b/post/5dda1f31-7719-46e9-9f5f-8584b6757a97/basic_reset.PNG" alt="스타일링이 없거나 reset.css 적용했을 경우"></p>
</li>
<li><p>normalize.css를 적용했을 경우
<img src="https://images.velog.io/images/hyorard-b/post/43131590-6198-4056-8911-d621bb38f10f/normalize.PNG" alt="normalize.css 적용했을 경우"></p>
</li>
</ul>
<p>이에 따라 <code>:focus</code> 클래스를 사용하여 <code>outline:none</code> 처리를 하여 외곽선을 지워버리는데, 이 때 접근성 문제가 발생한다.</p>
<hr>
<h2 id="키보드-포커싱-문제-발생">키보드 포커싱 문제 발생</h2>
<p>마우스를 사용하지 못하는 사용자는 키보드를 사용하여 페이지를 탐색하게 된다. <code>:focus</code> 클래스는 마우스 뿐 아니라, 키보드 포커싱까지 포함하기 때문에, 키보드로 페이지를 탐색하는 사용자는 어느 컨텐츠가 포커싱이 된 지 확인할 수 없게 된다.</p>
<hr>
<h2 id="focus-visible로-해결">:focus-visible로 해결</h2>
<p><code>:focus-visible</code> 클래스는 오직 키보드 포커싱만을 캐치한다. 이 클래스를 사용하면, 마우스 포커싱과 키보드 포커싱을 나눌 수 있게 된다.</p>
<p><a href="https://caniuse.com/?search=%3Afocus-visible">:focus-visible 브라우저 호환성</a></p>
<pre><code class="language-css">button:focus {
    outline: none;
    box-shadow: 0 0 0 4px rgba(147, 153, 210, 0.56);
}
button:focus:not(:focus-visible) {
    box-shadow: none;
}</code></pre>
<p>이 경우 버튼은 키보드 포커스가 아닌 포커스를 받으면 그림자를 나타내지 않게 되어, 클릭될 경우에 외곽선 또는 그림자가 나타나지 않는다. 그러나, 키보드를 통해 포커스를 받을 경우 그림자가 나타나게 되어 지금 탐색중인 영역이 어딘지 알 수 있게 된다.</p>
<ul>
<li><p>마우스 포커싱
<img src="https://images.velog.io/images/hyorard-b/post/f797a995-8084-49a7-8a4f-c418ea776de3/mouse-focus.PNG" alt="마우스 포커스를 받았을 경우"></p>
</li>
<li><p>키보드 포커싱
<img src="https://images.velog.io/images/hyorard-b/post/6b070569-e20c-416b-99ef-f7ad83efb64a/keyboard-focus.PNG" alt="키보드 포커스를 받았을 경우"></p>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>