TCP 세 번 째 악수 전송 데이터 프로 세 스 도해

6116 단어 TCP악수 하 다.

RFC 793 문서 에 SYN 로고 가 있 는 프로 세 스 패 키 지 는 데 이 터 를 휴대 할 수 없다.즉,세 번 악수 하기 두 번 은 데 이 터 를 휴대 할 수 없다 는 것 이다.중요 한 것 은 세 번 째 악 수 는 데 이 터 를 휴대 할 수 있 느 냐 하 는 것 이다.
먼저 결론:TCP 프로 토 콜 이 연 결 된 세 번 째 악수 과정 에서 세 번 째 악 수 는 데 이 터 를 휴대 할 수 있다.

위의 TCP 상태 변화 그림 의 연결 구성 부분 을 대조 하여 RFC 793 문서 의 설명 을 살 펴 보 겠 습 니 다.RFC 793 문서 에서 제시 한 설명 은 다음 과 같다.(중요 하지 않 은 부분 은 생략)

포 인 트 는 이'Data or controls which were queued for transmission may be included'다.즉,세 번 째 악 수 를 하 는 ACK 가방 은 데 이 터 를 휴대 할 수 있다 는 것 이다.
우선,세 번 째 악 수 를 하 는 가방 은 연결 발기인(이하 클 라 이언 트)이 포트 감청 자(이하 서버 로 약칭)에 게 보 내 는 것 이기 때문에 커 널 프로 토 콜 스 택 을 찾 아 SYN-RECV(그림 속 SYNRECEIVED)상태 시 가방 을 받 은 후 처리 과정 을 거치 면 됩 니 다.검색 을 통 해 찾 았 습 니 다.net\ipv 4 디 렉 터 리 아래 tcpinput.c 파일 의 tcprcv_state_프로 세 스 함수 가 이 과정 을 처리 합 니 다.그림:

이 함 수 는 실제 TCP 상태 기 입 니 다.TCP 연결 이 각 상태 에 있 을 때 패 킷 을 받 는 처리 에 사 용 됩 니 다.여기에 몇 개의 병렬 된 switch 문장 이 있 는데 함수 가 매우 길 기 때문에 차원 관 계 를 잘못 보기 쉽다.다음 그림 은 주목 할 필요 가 없 는 코드 를 간소화 한 후 SYN-RECV 상태의 처리 과정 입 니 다.

이 두 switch 문 구 는 병렬 되 어 있 음 을 반드시 주의해 야 한다.그래서 TCPSYN_RECV 상 태 는 합 법 적 으로 규범 화 된 2 차 악수 팩 을 받 은 후 즉시 socket 상 태 를 TCP 로 설정 합 니 다.ESTABLISHED 상태,아래 TCP 로 실행ESTABLISHED 상태의 case 는 포 함 된 데 이 터 를 계속 처리 합 니 다(있 으 면).
위 에 서 는 클 라 이언 트 가 보 낸 세 번 째 악수 의 ACK 에 데이터 가 포 함 될 때 서버 가 정상적으로 처리 할 수 있다 고 밝 혔 다.그럼 클 라 이언 트 쪽 은 요?클 라 이언 트 가 SYN-SEND 상태 일 때 세 번 째 ACK 가방 을 어떻게 보 내 는 지 살 펴 보 자.그림:

tcp_rcv_synsent_state_process 함수 의 실현 이 비교적 깁 니 다.여기에 마지막 관건 을 직접 붙 입 니 다.

일목요연 하 죠?if 조건 이 충족 되 지 않 으 면 단독 ACK 가방 에 직접 답장 하고,임의의 조건 이 충족 되면 inet 사용csk_reset_xmit_timer 함수 설정 타이머 가 짧 은 시간 을 기다 리 고 있 습 니 다.이 기간 에 데이터 가 있 으 면 데이터 에 따라 ACK 를 보 내 면서 ACK 에 답장 할 데이터 가 없다.
이전의 의문 은 해 결 된 셈 이다.
조건 1:sk->skwrite_pending != 0
이 값 은 기본적으로 0 입 니 다.그러면 어떤 상황 이 0 이 아 닙 니까?정 답 은 프로 토 콜 스 택 에서 데 이 터 를 보 내 는 함수 가 socket 상태 가 ESTABLISHED 가 아 닐 때 이 변 수 를++작업 하고 잠시 기다 리 며 데 이 터 를 보 내 려 고 합 니 다.그림 보기:

net/core/stream.c 의 skstream_wait_connect 함 수 는 다음 과 같은 조작 을 했 습 니 다:

sk->sk_write_pending 이 증가 하고 socket 연결 이 ESTABLISHED 상태 에 도착 하면 데 이 터 를 보 냅 니 다.그 건 설명 이 돼.
Linux socket 의 기본 작업 방식 은 막 힌 것 입 니 다.즉,클 라 이언 트 의 connect 호출 은 기본 적 인 상황 에서 막 히 고 세 번 의 악수 과정 이 끝나 거나 오류 가 발생 해 야 돌아 갑 니 다.그러면 nc 라 는 완전히 차단 소켓 으로 이 루어 지고 기본 socket 인 자 를 수정 하지 않 은 명령 행 애플 릿 은 connect 가 성공 하거나 실패 할 때 까지 기 다 려 서 데 이 터 를 보 낼 수 있 습 니 다.이것 이 바로 우리 가 세 번 째 악 수 를 할 수 없 는 가방 에 데이터 가 있 는 이유 입 니 다.
그러면 비 차단 소켓 을 설정 하고 connect 후 즉시 send 데 이 터 를 설정 합 니 다.연결 과정 이 순간 연결 에 성공 하지 않 으 면 세 번 째 악수 패 킷 데 이 터 를 볼 수 있 습 니 다.그러나 원본 을 여 는 네트워크 라 이브 러 리 는 socket 을 차단 하지 않 더 라 도 이 소켓 의 쓰기 가능 한 이 벤트 를 감청 하고 연결 이 성공 적 으로 되 었 는 지 다시 확인 해 야 데 이 터 를 쓸 수 있 습 니 다.이 점 을 절약 하기 위해 서 는 따 지지 않 는 성능 을 거의 무시 할 수 있 으 며,정말 안전 하고 믿 을 수 있 는 코드 보다 가치 가 있다.
조건 2:icsk->icskaccept_queue.rskq_defer_accept != 0
조건 이 이상해,deferaccept 는 socket 옵션 으로 accept 를 늦 추 는 데 사 용 됩 니 다.실제로 첫 번 째 데 이 터 를 받 은 후에 야 연결 을 만 듭 니 다.tcp_defer_accept 이 옵션 은 일반적으로 서버 에서 사용 되 며 socket 의 SYN 과 ACCEPT 대기 열 에 영향 을 줄 수 있 습 니 다.기본적으로 설정 하지 않 으 면 세 번 의 악수 가 끝나 면 socket 은 accept 대기 열 에 들 어가 고 응용 층 은 ACCEPT 와 관련 된 연결 을 감지 합 니 다.tcpdefer_accept 설정 후 세 번 의 악수 가 완료 되 었 습 니 다.socket 도 ACCEPT 대기 열 에 들 어가 지 않 고 SYN 대기 열 에 그대로 남아 있 습 니 다.이 매개 변 수 를 설정 한 서버 는 accept 후에 직접 read 할 수 있 습 니 다.반드시 데이터 가 있 고 시스템 호출 도 절약 할 수 있 습 니 다.
SYN 대기 열 저장 SYNRECV 상태의 socket,길 이 는 net.ipv4.tcpmax_syn_backlog 매개 변수 제어,accept 대기 열 이 listen 호출 시 backlog 매개 변수 설정,커 널 하 드 제한 은 net.core.somaxconn 에 의 해 제 한 됩 니 다.즉,실제 값 은 min(backlog,somaxconn)에 의 해 결 정 됩 니 다.
재 미 있 는 것 은 클 라 이언 트 가 먼저 포트 와 IP 에 바 인 드 한 다음 에 setsockopt(TCPDEFER_ACCEPT),그리고 connect 서버,이때 rskqdefer_accept=1 의 경우,이때 커 널 은 타이머 대기 데 이 터 를 설정 하여 함께 ACK 패 키 지 를 답장 합 니 다.나 는 개인 적 으로 이렇게 해 본 적 이 없다.설마 ACK 의 빈 가방 을 한 번 줄 여 성능 을 향상 시 키 기 위해 서 일 까?번 거 로 움 을 아 시 는 분 은 알려 주세요.감사합니다.
조건 3:icsk->icskack.pingpong != 0
pingpong 이라는 속성 은 실제 적 으로 소켓 옵션 으로 현재 링크 가 상호작용 데이터 흐름 인지 여 부 를 나타 낸다.만약 에 그 값 이 1 이면 상호작용 데이터 흐름 으로 나타 나 고 지연 확인 체 제 를 사용 할 것 이다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기