서로다른 컴퓨터끼리의 데이터 통신을 위한 프로토콜이다. OSI의 4계층인 전송계층(transport layer)에서 사용한다.
데이터 전송 과정에서 패킷이 손실될 수도 있다. 이 때, TCP는 어떤 패킷이 손실됐는지에 대한 정보를 알기 위해 모든 데이터 byte에 번호를 매긴다.

TCP header에는 sequence number이라는 필드가 존재한다. 해당 segment에 들어있는 data들 중, 가장 첫 번째 data byte에 매겨진 숫자가 sequence number가 된다.
TCP는 연결지향(connection-oriented)이다. 송신자와 수신자가 서로 연결되는 것에 동의해야 데이터를 주고받을 수 있다. sending buffer, receiving buffer를 구축하면 두 버퍼간에 데이터를 읽고 쓰는 형식으로 주고받을 수 있다.

1) 상대와 연결설정을 하기 위해 SYN을 보낸다.
2) 상대는 그 메시지에 대한 ACK + 나도 통신 준비가 되었다는 SYN을 함께 보낸다.(piggybacking)
3) 2번에서 받은 메시지에 대해 ACK을 보낸다.

1) 상대와 연결해제를 하기 위해 FIN을 보낸다.
2) 상대는 그 메시지에 대한 ACK + 나도 해제하겠다는 FIN을 함께 보낸다.(piggybacking)
3) 2번에서 받은 메시지에 대해 ACK을 보낸다.
client에서 server에게 더이상 보낼 데이터가 없어 FIN을 보냈지만, server는 client에게 보낼 데이터가 남아있는 상황인 경우, FIN과 ACK을 따로 보내게 된다.
1) 상대와 연결해제를 하기 위해 FIN을 보낸다.(client->server)
2-1) 상대는 그 메시지에 대한 ACK을 보낸다.
2-2) 상대와 연결해제를 하기 위해 FIN을 보낸다.(server->client)
3) 2번에서 받은 메시지에 대해 ACK을 보낸다.
2-1과 2-2사이에 server에서 client로 아직 처리되지 않은 데이터를 보낼 수 있고, client는 server에게 데이터를 보낼 수 없다. 이 상태를 Half-Close이라고도 한다.
client->server방향의 연결은 이미 해제되어 있는 상황에서, client가 FIN을 받아 ACK을 server로 보내자마자 CLOSED된다고 가정하자. 이 경우 두 가지 문제가 발생할 수 있다.
client가 server로 FIN에 대한 ACK을 보냈는데 이 ACK이 손실된 상황에 문제가 발생할 수 있다. server는 ACK을 받지 못했기 때문에 FIN을 다시 한 번 보내지만, client는 CLOSED state이기 때문에 여전히 ACK을 보낼 수 없다.
client1이 연결을 해제하고, client2가 새롭게 연결됐다고 하자.
client2의 port number가 우연히 client1이 사용하던 port number와 동일한 상황이다.
server가 client1에게 보내야 했던 패킷이 뒤늦게 client2에게 도착했는데, 또 우연히 sequence number의 범위마저 비슷해 client2가 자신의 패킷으로 착각할 수 있다.

따라서 client가 last ACK을 보내고, 2 * MSL만큼의 시간동안 TIME-WAIT상태로 걸어준다.