[컴퓨터 네트워크] Tcp에 대한 자세한 설명

머리말

앞서 전송 계층 프로토콜 Udp에 대해 배웠습니다. 오늘은 Tcp에 대해 알아 보겠습니다. Tcp는 Udp보다 복잡하지만 안정적입니다. 많은 시나리오에서 이러한 안정성이 필요합니다.

Tcp 프로토콜 세그먼트 형식

여기에 이미지 설명을 삽입하세요.

형식 측면에서만 Tcp는 Udp보다 훨씬 복잡합니다. 그렇다면 Tcp 헤더와 페이로드를 어떻게 분리해야 할까요?

먼저 헤더의 처음 20바이트를 고정해야 하는데, 먼저 처음 20바이트를 추출하여 4자리 헤더 길이를 찾은
다음, 헤더 길이 * 4 -20 에 옵션이 있는지 확인합니다
. 옵션의 바이트, 나머지는 데이터입니다.

TCP 신뢰성

대량의 패킷 손실, 고장, 중복, 검증실패, 전송속도 저하, 네트워크 장애 등은 모두 신뢰성이 낮다는 것을 의미하며, 전송거리가 길어지기 때문에 신뢰성에 많은 문제가 발생하게 됩니다. 문제. TCP는 응답 시스템을 도입했습니다 .

C가 S에게 데이터를 보낸다면 S가 C에게 응답할 때만 C는 자신의 데이터가 S에게 전송된 것으로 간주합니다. 일정 시간 동안 기다린 후에도 응답이 수신되지 않으면 C는 자신이 보낸 데이터가 S로 전송된 것으로 간주합니다. S로 전송되었습니다. 손실된 경우 시간 초과 재전송이 트리거됩니다.

전송 효율성을 높이기 위해 여러 개의 TCP 메시지가 동시에 전송되므로 반대쪽에 도착하는 데이터가 순서에 맞지 않게 됩니다. 순서가 맞지 않는 것은 바로 우리가 신뢰성을 위해 원하는 작업이므로 TCP 메시지는 번호가 매겨질 예정이다 .

바이트 스트림 지향

애플리케이션 계층은 데이터를 TCP 송신 버퍼에 복사하고 전체 송신 버퍼를 uint8 단위로 나눕니다. 따라서 송신 버퍼에는 자연스럽게 번호가 지정됩니다(배열 첨자).

대응 메커니즘

우리는 위에서 TCP가 응답과 숫자를 요구한다는 것을 알고 있습니다. 응답은 실제로 ACK 필드를 전달하는 TCP 메시지이고 32비트 시퀀스 번호는 우리가 숫자라고 부르는 것입니다. 피어는 이에 대해 ACK로 우리에게 응답해야 합니다. 시퀀스 번호.

예를 들어, C 끝은 시퀀스 번호 10으로 32비트 메시지를 보내고 S 끝은 시퀀스 번호 11로 32비트 확인 메시지를 반환합니다.

송신 순서 번호: 현재 메시지의 번호입니다.
확인 시퀀스 번호: 이전의 모든 메시지가 수신되었으며 이 시퀀스 번호부터 시작하여 전송되어야 함을 나타냅니다.

Tcp 메시지에는 피기백 응답 메커니즘, 즉 S가 ACK를 보낼 때 C에게 보내고자 하는 정보도 포함되어 있기 때문에 두 개의 독립적인 필드로 설계되어야 하며 함께 다중화될 수 없습니다.

시간 초과 재전송

데이터 손실의 두 가지 가능성:
1. 실제로 데이터가 중간에 손실되었습니다.
2. 데이터가 손실되지 않았지만 ACK가 중간에 손실되었습니다.

첫 번째 경우에는 데이터를 재전송해야 하며, 이를 위해서는 TCP가 재전송을 지원하기 위해 데이터를 일시적으로 저장할 수 있어야 합니다.
두 번째 경우에는 해당 ACK만 손실되면 다른 ACK의 확인 시퀀스 번호가 변경되지 않으므로 다른 ACK를 참조할 수 있습니다.

대기 시간: 플랫폼마다 다르며 Linux에서는 500ms를 기준으로 n*500 방식으로 동적으로 조정됩니다.

흐름 제어

TCP에는 역시 전이중 방식인 수신 버퍼와 송신 버퍼가 있지만 버퍼 크기가 있는 한 다음 시나리오를 상상해 보세요.

C는 S에게 메시지를 보내지만 S의 수신 버퍼는 이를 수용할 수 없습니다. 이 경우 S는 응답 없이 삭제된 패킷만 폐기할 수 있으며, 잠시 후 C는 패킷을 재전송하게 됩니다.

자세히 살펴보면 매우 비효율적이라는 것을 알 수 있는데, 메시지는 반대 호스트까지 쭉 이동하지만 상대 호스트가 이를 수신할 수 없기 때문에 폐기됩니다.이 문제를 해결하기 위해 TCP 메시지에는 필드가 있습니다. 16비트 창 크기라고 합니다 .

창 감지:
양쪽 끝은 정기적으로 상대방에게 데이터가 없는 TCP 메시지를 보내 상대방의 수신 능력을 문의하고 전송되는 데이터의 속도와 크기를 조정합니다. (이 프로세스는 양방향입니다.)

슬라이딩 윈도우(중요)

TCP 프로토콜의 경우 신뢰성이 주요 연구 이슈이지만 효율성 역시 TCP가 고려해야 할 이슈이다.

보내는 사람은 상대방이 받을 수 있는 경우에만 동시에 보낼 수 있습니다.

1. 일반 상황
여기에 이미지 설명을 삽입하세요.

송신 버퍼는 슬라이딩 창을 통해 세 개의 영역으로 나뉩니다.

왼쪽 영역 : 전송 및 확인된 데이터 - 덮어쓰기 가능
가운데 영역 : 직접 전송할 수 있지만(크기 제한) 응답이 수신되지 않은
영역 오른쪽 : 전송된 데이터 영역 아직 전송되지 않았습니다.

슬라이딩 윈도우의 크기는 상대방의 수신 능력과 관련이 있어야 합니다.

1.5 슬라이딩 윈도우를 이해하는 방법

바이트 스트림

2. 특별한 상황

1. 슬라이딩 윈도우는 왼쪽의 데이터가 의미가 없기 때문에 오른쪽으로만 이동할 수 있습니다.

2. 크거나 작아지는 것의 본질은 와인엔드를 조절하는 것이며, 상대방의 창 크기에 따라 슬라이딩 창이 떠있습니다.

3. 0이 되어 상대방이 데이터를 수신할 수 없음을 나타냅니다. (창 감지 및 창 알림 수행)

4. 응답도 순서대로 도착해야 합니다.
응답 번호: winstart = seq,
응답 창 크기: winend = winstart + win;

5. 손실 문제

a.첫 번째 것이 유실되었으므로
재전송하여 재발급해 주십시오.

b. 가운데가 없어졌는데,
오른쪽으로 스와이프하면 첫 번째가 됩니다.

c.마지막 것을 잃어버리면
가장 왼쪽의 것도 됩니다.

빠른 재전송: (고속 재전송)
메시지가 손실되고 동일한 승인이 세 번 연속 수신되면 즉시 재전송됩니다.

재전송 하한: 타임아웃 재전송
재전송 상한: 빠른 재전송

혼잡 제어

네트워크에 문제가 있으면 TCP도 정책 제어를 구현합니다.

패킷 손실도 마찬가지이며, 손실이 적다는 것과 손실이 많다는 차이가 있으며, 패킷 손실이 계속된다면 네트워크 문제입니다.

대량의 패킷이 손실되면 보낸 사람의 전송 전략은 기다렸다가 다시 보내는 것입니다! !

네트워크가 마비되면 모든 호스트가 다시 재전송을 하게 되어 마비된 네트워크를 복구하기가 더욱 어려워지므로, 네트워크 정체가 발견되면 전송량을 줄이는 전략을 채택하고 있습니다. 일반적으로 다음 두 가지 요구 사항을 충족해야 합니다.

1. 네트워크 정체가 증가하지 않는지 확인합니다.
2. 네트워크 복구가 개선되면 가능한 한 빨리 네트워크 통신을 복원합니다.

TCP는 느린 시작 메커니즘을 도입합니다.

네트워크 정체가 발생하면 송신자는 기본적으로 네트워크 정체의 심각도를 알고 네트워크 상태를 감지해야 합니다.

Congestion Window
네트워크 상태 측정 필요 - Congestion Window

네트워크 상태는 수시로 변하는데, 네트워크의 상태를 측정하려면 혼잡 윈도우(Congestion Window)의 크기가 변해야 한다.

因此发送方的滑动窗口 = min(16位窗口大小,网络的拥塞窗口)

혼잡 창의 증가율은 기하급수적입니다. 느린 시작은 초기 단계에서는 느리고 이후 단계에서는 매우 빠르다는 것을 의미합니다.

1. 느린 시작에 대한 임계값이 있습니다.
2. 혼잡 창이 이 임계값을 초과하면 더 이상 기하급수적으로 증가하지 않고 선형적으로 증가합니다.
3. 시간이 초과되어 재전송될 때마다 느린 시작 임계값(ssthresh)이 절반이 됩니다. 원래 값의 동시에 혼잡 창은 1로 설정됩니다(곱셈적으로 감소됨).

지연된 응답

ACK 응답은 즉시 반환되며 반환되는 창 크기는 더 작을 수 있습니다.

상대방에게 더 큰 승리 크기를 발표함으로써 상대방은 더 큰 확률로 전송 효율성을 향상시킬 수 있습니다. 상위 레이어에 읽을 시간을 더 주고, 이 시간 동안 최대한 빨리 읽고, 더 많이 읽으세요.

피기백 답장

ACK 히치하이킹.

플래그 비트

  • 깃발의 성격

다양한 유형의 메시지를 식별하는 이진 비트

  • 깃발은 왜 있는 걸까요?

다른 플래그는 다른 서비스를 제공합니다.

특정 플래그 위치

ACK: 데이터를 전달할 수 있는 확인 응답 메시지(피기백 응답)
SYN: 연결 요청 메시지(3방향 핸드셰이크)
FIN: 연결 끊김 메시지(4파동)
PSH: 버퍼 데이터를 가져오는 즉시 상대방의 애플리케이션 계층에 요청 가능 Go ( 多路转接)
RST: 상대방에게 다시 연결하라고 지시합니다. (연결이 재설정되었습니다.)
URG: 순서대로 도착했는데 줄을 서고 싶어요? (긴급 데이터) 16비트 긴급 포인터, 페이로드의 긴급 데이터 오프셋. 긴급 데이터(대역 외 데이터)는 1바이트에 불과합니다. (다운로드 취소 사례) Recvfrom의 MSG_OOB 옵션입니다.

세 번의 악수

여기에 이미지 설명을 삽입하세요.

  • 1. 연결이란 무엇입니까?
    OS 내에는 여러 개의 연결이 설정되어 있어야 하며 OS는 이러한 연결을 관리해야 합니다.
    연결을 유지하는 데는 비용이 많이 들고 CPU와 메모리 리소스를 소비해야 합니다.

  • 2. 왜 세 번이나요?
    3방향 핸드셰이크 프로세스 동안 양측의 운영 체제는 독립적으로 TCP를 완료합니다
    . 연결: 연결을 트리거하고 완료를 기다립니다.
    수락: 설정이 완료될 때까지 기다리고 연결을 얻습니다.

    클라이언트의 경우 마지막 ACK가 전송되면 링크가 설정된 것으로 간주됩니다.
    서버의 경우 마지막 ACK를 받은 후에만 빌드를 위해 리소스를 소비합니다.

    따라서 3방향 핸드셰이크의 핵심은 서버가 마지막 ACK를 수신했다는 것입니다. ACK가 수신되지 않으면 두 가지 모두 인지 불일치가 발생하며, 이때 클라이언트는 서버에 메시지를 보내고 서버는 RST로 응답하여 연결을 재설정합니다.

    • 두 번의 핸드셰이크가 있는 경우 SYN+ACK가 발행되는 한 리소스가 낭비됩니다. 쉽게 SYN洪水攻击. TCP 자체는 보안 문제 해결을 고려하지 않지만 TCP에는 보안 허점이 있을 수 없습니다. 따라서 SYN 플러드를 방지해야 합니다.
    • 3번 이상의 핸드셰이크가 있는 경우 마지막 ACK 문제는 여전히 해결되지 않으며, 짝수 핸드셰이크인 경우 마지막 ACK에 대한 위험은 서버가 부담하고, 홀수 핸드셰이크의 위험은 클라이언트가 부담하게 됩니다. . 서버 측에서는 많은 양의 데이터를 저장하므로 예외가 불가피하지만 두 번 또는 심지어 핸드셰이크도 부적절합니다.
    • 3-way handshake의 장점:
      1. 뚜렷한 허점이 없음 예외가 발생하면 비용이 클라이언트에 접목됨
      2. 양측 간 통신 채널이 원활한지 확인 검증하는 데 드는 최소 비용 부드러운(전이중)(수신 및 전송)
  • 3. 상태 변경
    SYN_SENT:
    SYN_RCVD 동기 전송:
    ESTABLiSH 동기 수신: 설정 완료

네 번 흔들다

여기에 이미지 설명을 삽입하세요.
4번의 흔들림은 양측이 연결과 연결해제에 대한 합의를 이루기 위한 최소한의 비용입니다! 두 당사자 모두 동의해야 합니다(둘 중 누구도 메시지를 보내지 않음).

상태 변경:

클라이언트가 종료되고 서버가 close를 호출하지 않으면 서버는 CLOSE_WAIT 상태로 들어가고 서버는 FIN_WAIT2 상태로 들어갑니다.

여기에 이미지 설명을 삽입하세요.

잠시 후 클라이언트의 FIN_WAIT2는 사라지고, 서버는 여전히 CLOSE_WAIT 상태입니다. 따라서 서버측에서는 파일 설명자를 꺼주세요!

close를 호출한 후 서버는 즉시 LAST_ACK 상태로 진입하고 피어에게 FIN을 전송하며, 피어가 닫혀 있으면 서버도 몇 번의 재전송 후에 연결을 끊습니다.

적극적으로 연결을 끊은 당사자는 TIME_WAIT 상태로 들어가야 하며 즉시 다시 시작하려는 경우 실패합니다. 그 이유는 기본 연결이 여전히 TIME_WAIT 상태이기 때문입니다.

  • 1. TIME_WAIT를 입력하는 이유

    TCP 프로토콜은 적극적으로 연결을 끊는 당사자가 두 MSL 시간(메시지가 네트워크에 존재할 수 있는 최대 시간) 동안 기다려야 한다고 규정합니다.

    • 1. 새로운 연결에 영향을 미치지 않도록 네트워크의 패킷이 가능한 한 빨리 소멸되도록 하십시오.
    • 2. 상대방이 마지막 ACK를 수신했는지 확인합니다. 상대방이 마지막 ACK를 받지 못하면 다른 FIN을 보냅니다.
  • 2. 서버가 대기를 원하지 않는 경우

    //设置地址可以复用,令服务器立马重启
    setsockopt(int sockfd,int level,int optname,const void* optval,socklen_t optlen)
    参数:
    sockfd:套接字
    level:当前在哪一层(SOL_SOCKET)
    optname:(SO_REUSEADDR | SO_REUSEPORT)
    optval:1
    optlen:len
    

끈끈한 가방 문제

TCP에는 UDP의 메시지 길이 필드가 없으며 두 데이터 사이의 경계를 알 수 없습니다.이 문제는 패킷 고정 문제입니다.

해결책: 두 패키지 사이의 경계를 명확히 합니다(상위 레이어에서 완료).

TCP 예외

프로세스 종료/머신 재시작: 프로세스 종료는 일반적인 종료와 마찬가지로 파일 설명자를 해제하고 계속 FIN을 보냅니다(운영 체제는 모든 관련 리소스를 재활용합니다).

기기의 전원이 꺼졌거나 네트워크 케이블이 끊어진 경우: 피어는 연결이 아직 존재한다고 생각합니다. 수신 측에서 쓰기 작업을 수행하고 연결이 더 이상 존재하지 않는 것을 발견하면 재설정됩니다. 서버는 연결 유지를 보냅니다. 타이머 및 송신 측도 재설정할 수 있습니다.

Listen의 두 번째 매개변수

두 번째 파라미터를 1로 설정하여 서버에 접속하고, 일정 레벨 이후에는 SYN_RECV를 입력합니다. 즉, 링크는 2개만 설정될 수 있습니다.

TCP 프로토콜은 하위 계층에서 전체 연결 대기열을 유지해야 하며 최대 길이는 두 번째 매개변수 + 1입니다.

반 연결 대기열에는 연결이 없으며 시간은 매우 불연속적입니다.

전체 연결 대기열은 너무 길거나 비어 있을 수 없습니다. 전체 연결의 길이는 서버에서 처리하는 길이가 아니라 "대기" 장소입니다.

1. OS 리소스를 너무 많이 소모하므로 서버에서 사용하는 것이 좋습니다
2. 테일 대기 시간이 너무 깁니다.

추천

출처blog.csdn.net/m0_73209194/article/details/132276237