TCP(Transmison Control Protocol)
신뢰성 있는 통신을 제공하기 위한 프로토콜
TCP는 연결 지향적 프로토콜로서 데이터를 전송하고자 하는 목적지 호스트와 발신지 호스트가 서로 접속 과정을 거쳐 접속이 이루어졌을 때 데이터를 전송하게 된다. 이렇게 접속 과정을 거치는 이유는 접속 과정을 통해 송신지 호스트와 수신지 호스트가 각각 정보를 교환해 신뢰성 있는 데이터 전송을 보장하기 위해서이다.
서로 접속이 되었을 때 그때 데이터를 서로 전송한다(전이중 서비스)
인터넷에 보낸 패킷은 네트워크의 상태에 따라 서로 다른 경로를 통해서 목적지 호스트로 갈 수 있다. 이때 먼저 보낸 패킷이 나중에 보낸 패킷보다 늦게 도착하는 경우도 당연히 생기게 된다. 이럴 경우 TCP에 의해 각 패킷은 순서가 매겨지기 때문에 먼저 보낸 패킷이 나중에 도착하더라도 데이터를 추출하는 과정에서 데이터의 순서에 맞게 재조합된다. 이런 과정을 "데이터에 순차성이 있다"는 말로 표현할 수 있다.
각 패킷의 순서가 있어서 데이터를 뒤죽박죽 보내도 결국엔 다시 조합이 가능하다.
흐름 제어는 일상에서의 예로 설명하면 이해하기 수월하다. 전화를 걸고 있는 상황에서 상대방의 말이 너무 빨라 알아듣기 힘들다면 우리는 천천히 말해달라고 요구한다. 그러면 상대방은 말이 너무 빠르다는 것을 감지하고 그 다음부터는 천천히 얘기할 것이다.
네트워크도 마찬가지다. 송신지 호스트에서 패킷을 보내는데, 수신지 호스트가 감당하기 힘들 정도로 빨리 보낸다면 수신지 호스트의 버퍼가 넘쳐버리고 말 것이다. 이렇게 버퍼가 넘치는 것을 방지하기 위해서 TCP에서는 '슬라이딩 윈도우'라는 방식을 이용해서 송수신지가 버퍼의 크기를 가변적으로 조절하며 흐름 제어를 수행한다. 이렇게 흐름 제어를 하게 되면 최대한 빠르면서도 안전한 전송을 할 수 있다.
슬라이딩 윈도우라는 방식으로 TCP는 흐름제어를 수행한다.
TCP는 TCP 헤더에 있는 체크섬 값을 이용해서 TCP 패킷이 이상 없이 전송되었는 지 확인한다.
만약, 이상없이 전송되었다면 송신지로 확인 메시지(ACK 패킷)를 보내고 이상이 발생했다면 이상이 발생한 패킷을 버리고 확인 메시지를 보내지 않는다. 송신지는 자신이 보낸 패킷에 대해서 일일이 확인 메시지를 기다리는데, 만약 전송 과정에서 이상이 생겨 수신지로부터 확인 메시지가 없다면 패킷을 재전송하게 되어있다.
TCP 헤더에 있는 체크섬 값을 이용해서 오류제어를 한다.
일반적으로 하나의 호스트에는 하나의 NIC가 있고 하나의 IP가 부여된다.
호스트로 들어오거나 나가는 패킷은 모두 동일한 IP로 설정되어 나가게 되는데, IP만으로는 여러 프로세스간의 데이터가 구별되지 않는다.
TCP는 포트번호를 이용해서 각각의 프로세스에게서 송수신되는 패킷을 구별해서 나누어준다.
IP + PORT 번호로 프로세스 간의 통신을 한다.
세그먼트(Segment)란?
데이터에 TCP 헤더가 붙은 전송계층의 패킷

발신지 호스트의 애플리케이션의 포트 주소를 적는 부분이다.
목적지 호스트의 애플리케이션의 포트 주소를 적는 부분이다.
순서 번호는 전달하고자 하는 스트림의 순서 번호를 나타내는 값이다. 크기가 큰 원본 데이터는 한 번에 전달하는 것이 불가능하다. 이럴 경우 원본 데이터를 여러 개의 세그먼트로 나누는데, 데이터의 시작점 위치에 따라 이 값이 설정된다.

확인 응단 번호는 수신지에서 TCP 세그먼트를 받고 제대로 왔다면 발신지에게 제대로 왔다는 것을 알려주기 위한 번호다. 만약, 수신지 노드 A가 발신지 노드 B로부터 순서 번호 1500이고 데이터의 길이가 100인 TCP 세그먼트를 받았다면 확인 응답 번호로는 1600을 보내준다. 여기서 1600은 발신지 노드가 B가 다음에 보낼 순서 번호다.
순서 번호와 확인 응답 번호는 오류 제어를 하는 데 사용된다. 예를 들어, 발신지 호스트에서 TCP 세그먼트를 보냈는데, 중간에 잡음이 섞여서 데이터가 변질되었다면 수신지 호스트는 확인 응답을 보내주지 않는다. 만약, 확인 응답이 일정 시간동안 없으면 발신지 호스트는 이전에 보낸 TCP 세그먼트를 다시 보내게 된다. 이렇게 순서 번호와 확인 응답 번호를 이용해서 일일이 확인하기 때문에 TCp는 신뢰성있는 데이터 통신을 제공할 수 있는 것이다.
IP와 마찬가지로 헤더의 길이를 워드 단위(4바이트)로 나타내는 부분이다. TCP 헤더 역시 IP 헤더와 마찬가지로 헤더 옵션의 유무에 따라 20바이트에서 최대 60바이트까지 가변적이다. 만약, 헤더 크기가 20바이트였다면 20/4 = 5가 되므로 DataOffSet 필드는 5로 설정된다.
향후 사용을 위해 예약되어 있는 필드다.
이 비트들은 흐름 제어와 연결 설정 및 종료를 위해 사용되는 비트들이다. 각각 1비트로 되어있고 해당 비트가 로 설정되면 의미를 갖게되고 해당 세그먼트의 용도가 어떠한지 결정된다.

송수신지 버퍼의 크기를 나타내는 필드다. 송수신지 버퍼를 다른 말로 윈도우라고 하는데, 흐름 제어를 수행할 때 참조되는 필드다.
IP와 마찬가지로 TCP 헤더와 데이터가 이상 없이 제대로 전송되었는지 확인할 때 비교가 되는 값이다. 만약, 전속 도중 잡음에 의해 1비트라도 변경이 되었다면 체크섬 확인 과정에서 결과가 0이 나오지 않는다.
이 필드는 URG 제어 비트가 설정된 긴급 상황에서 사용되는 필드다. 만약, 송신지에서 세그먼트를 보내고 있는데, 수신지로부터의 응답이 자못되었거나 기타 다른 이유로 무엇인가 이상이 발견되면 긴급 데이터를 실은 세그먼트를 수신지로 보낸다. 그러면 URG 비트가 설정된 세그먼트를 받은 수신지는 긴급 포인터에 설정된 값을 이용해서 긴급 데이터를 추출하고 순서에 상관없이 애플리케이션에 가장 먼저 전달하게 된다.
TCP는 최대 40바이트까지의 옵션을 가질 수 있는데, 만약 옵션을 가진다면 옵션이 들어가는 필드다. 이러한 옵션은 4바이트 단위로 정렬되어야 하는데, 만약 옵션이 4바이트가 되지 않는다면 모두 0을 붙여서 4바이트 단위로 만든다. 이를 패딩이라고 한다.
애플리케이션의 데이터가 들어가는 부분이다.
컴퓨터가 어떻게 2000km가 넘는 지구 반대편에 있는 컴퓨터와 접속해서 데이터를 받아 오는 지 알아보자
만약 웹브라우저로 구글 사이트에 접속한다고 가정하고 내부적으로 어떠한 일이 일어나는지 알아보자
패킷은 IP 주소를 가지고 최종 목적지로 찾아가고 물리 주소를 통해 다음 목적지까지 찾아간다고 했다.

네트워크 A에 있는 1.1.1.100 컴퓨터에서 네트워크 B에 있는 2.2.2.100 컴퓨터로 접속하려면 게이트웨이 1.1.1.1에게 패킷이 먼저 전해져야한다. 패킷을 받은 게이트웨이는 IP헤더에 있는 목적지 IP 주소(2.2.2.100)를 기준삼아 가장 비용이 적은 경로를 산출해서 인터넷에 있는 다음 라우터 또는 호스트로 패킷을 보내게 된다.
NIC에서 데이터가 어떤 형식으로 나갈까?

위 그림은 컴퓨터에 있는 이더넷 카드에서 나가는 데이터의 구조를 잘 보여준다. 이러한 데이터 구조는 전압의 높낮이에 의해 구별되는 전기적 신호로서 전압이 있는 상태가 1을 표현하고 없는 상태가 0을 표현하게 된다.
이더넷에서는 실제로 케이블을 통해 이러한 구조를 가지는 신호가 나간다. 이렇게 IP 헤더 앞에 물리 헤더가 붙은 구조를 프레임이라 부른다. OSI 모델에서 부르는 하나의 패킷 단위다.
물리 계층에 해당하는 패킷을 프레임이라고 부르고 네트워크 계층 패킷을 데이터그램이라 부르고 전송계층 패킷을 세그먼트라고 부른다.
이더넷에서 사용되는 프레임은 실제로 위와 같은 형식으로 되어 있다. 제일 먼저 6바이트 목적지 물리 주소가 오고 다음으로 6바이트 발신지 물리 주소가 온다. 다음으로 프로토콜 타입이 오는데, 뒤 오는 데이터가 어떤 프로토콜이냐에 따라 각각 고유 번호로 설정되는 부분이다.
위 그림에서 데이터 부분을 제외한 앞부분을 프레임 헤더라고 부른다. 그렇지만 이러한 프레임헤더는 NIC의 종류마다 그 구조가 다르다. 위 그림은 가장 보편적인 이더넷의 프레임 헤더 구조를 나타낸 것이다. 이더넷은 Ethernet Version-2 헤더 형식의 구조를 가지고 있는데, 줄여서 그냥 Ethernet-II 헤더라고 부른다. 데이터 부분에 오는 것은 보통 IP 헤더가 붙은 데이터그램이거나 경우에 따라서 다른 프로토콜 데이터가 오기도 한다.