programing

닫힘 소켓과 종료 소켓의 차이

goodsources 2022. 7. 16. 14:04
반응형

닫힘 소켓과 종료 소켓의 차이

C에서는 소켓을 닫으면 소켓이 파괴되어 나중에 재사용할 수 있다는 것을 알았습니다.

운운운운 운운?설명에 따르면 이 소켓에 대한 듀플렉스 접속의 절반이 닫힙니다. 그 은 '소켓'처럼 요?close★★★★★★★★★★★★★★★★★★?

의 어떤 도 사람들에게 해야 하는지 .shutdown ★★★★★★★★★★★★★★★★★」closeTCP 프로토콜 수준에서 동작하기 때문에 추가할 필요가 있습니다.

표준 TCP 접속은 4방향 최종화에 의해 종료됩니다.

  1. 참가자는 송신할 데이터가 없어지면 FIN 패킷을 다른 참가자에게 송신합니다.
  2. 상대방이 FIN의 ACK를 반환합니다.
  3. 상대편도 데이터 전송을 완료하면, 다른 FIN 패킷을 송신합니다.
  4. 첫 번째 참가자는 ACK를 반환하고 전송을 종료합니다.

다만, TCP 접속을 종료하는 다른 「신흥」방법이 있습니다.

  1. 참가자가 RST 패킷을 송신해, 접속을 포기했습니다.
  2. 상대편도 RST를 수신하고 나서 접속을 포기합니다.

Wireshark를을 사용하여 Wireshark를 했습니다.shutdownFIN 패킷을 다른 쪽 끝에 송신합니다만, 그것뿐입니다.상대방이 FIN 패킷을 송신할 때까지, 데이터를 수신할 수 있습니다.일단 이런 일이 일어나면Receive결과를 수 .따라서 "송신"을 처음 종료한 경우 데이터 수신이 완료되면 소켓을 닫아야 합니다.

'하다'라고 '하다'라고 부르죠.close접속이 아직 활성화되어 있는 동안(다른 한쪽이 활성화되어 시스템버퍼에 송신되지 않은 데이터가 있는 경우도 있습니다), RST 패킷이 다른 쪽으로 송신됩니다.이것은 오류에 좋습니다.예를 들어 상대방이 잘못된 데이터를 제공했거나 데이터 제공을 거부한 경우(DOS 공격?) 소켓을 즉시 닫을 수 있습니다.

규칙에 대한 나의 견해는 다음과 같다.

  1. shutdown 전에close 수 있으면
  2. 셧다운을 결정하기 전에 수신을 완료한 경우(0 사이즈의 데이터 수신) 마지막 전송이 완료된 후 연결을 닫습니다(있는 경우).
  3. 정상적으로 접속을 종료하는 경우는, 접속을 셧다운 해(SHUT_WR, 및 이 시점 이후의 데이터 수신에 관심이 없는 경우, SHUT_RD 를 사용해), 0 사이즈의 데이터를 수신할 때까지 기다린 후, 소켓을 닫습니다.
  4. 어떤 경우에도 다른 에러가 발생했을 경우(타임아웃 등), 소켓을 닫기만 하면 됩니다.

SHUT_RD 및 SHUT_에 최적인 구현WR

다음 사항은 테스트되지 않았습니다.자신의 책임으로 신뢰해 주십시오.하지만 저는 이것이 합리적이고 실용적인 방법이라고 생각합니다.

TCP 스택이 SUT_RD만으로 셧다운을 수신했을 경우, 이 접속은 데이터 예측 없음으로 마크됩니다.의 보류 중 및 " " "read(어느 스레드에 있든) 요구는 제로 사이즈로 반환됩니다.그러나 연결은 여전히 활성 상태이며 사용할 수 있습니다. OOB에 관한 것입니다. 는 이한 모든 .단, 다른 쪽에는 패키지가 발송되지 않습니다.

TCP 스택이 SHUT_WR만을 사용하여 셧다운을 수신했을 경우, 이 접속에 데이터를 송신할 수 없는 마크를 붙여야 합니다.보류 중인 쓰기 요청은 모두 완료되지만 이후 쓰기 요청은 실패합니다.또한 FIN 패킷이 다른 쪽으로 전송되어 더 이상 전송할 데이터가 없음을 알립니다.

이것은 Beej의 네트워킹 가이드에서 설명하고 있습니다. shutdown는 한쪽 방향 또는 양쪽 방향의 통신을 차단하는 유연한 방법입니다.가 " " " 인 SHUT_RDWR을 모두 : 「송수신」).closeclose소켓을 실제로 파괴하는 방법입니다.

★★★★★★★★★★★★★★★★ shutdown피어(peer)가 이미 전송한 보류 데이터를 계속 수신할 수 있습니다(Joey Adams가 이 점에 주목해 주셔서 감사합니다).

, Linux 에서는, i i 、 Linux , linux i i i두 i 。shutdown()되어 있는 다른 pthread를 합니다.connect()조기 중단.

에서는, (OSX)를 호출하고 .close()손에 넣기에 충분했다connect()실패하다.

에는 몇 가지 제한이 있습니다.close()그것을 사용하면 피할 수 있다shutdown()대신.

close()는, TCP 접속으로 양쪽의 방향을 종단합니다.다른 엔드포인트에 데이터 전송이 완료되었지만 데이터를 수신하려고 할 수 있습니다.

close()는 디스크립터 참조 수(파일 테이블엔트리에서 유지되며 파일/디스크립터를 참조하는 현재 열려 있는 디스크립터의 수를 카운트)를 줄이고 디스크립터가 0이 아닌 경우 소켓/파일을 닫지 않습니다.즉, 포킹 중인 경우 참조 수가 0으로 떨어진 후에만 정리가 수행됩니다.와 함께shutdown()참조 카운트를 무시하고, 통상의 TCP 클로즈 시퀀스를 개시할 수 있습니다.

파라미터는 다음과 같습니다.

int shutdown(int s, int how); // s is socket descriptor

int how다음과 같은 경우가 있습니다.

SHUT_RD또는0이후 수신은 허용되지 않습니다.

SHUT_WR또는1더 이상의 전송은 허용되지 않습니다.

SHUT_RDWR또는2더 이상 송수신할 수 없습니다.

플랫폼에 따라 다르겠지만 어쨌든 제가 본 최고의 설명은 여기 msdn 페이지에 있습니다.여기에서는 셧다운, 링거 옵션, 소켓 폐쇄 및 일반적인 접속 종료 시퀀스에 대해 설명하고 있습니다.

요약하면 shutdown을 사용하여 TCP 수준에서 shutdown 시퀀스를 전송하고 close를 사용하여 프로세스 내의 소켓 데이터 구조에서 사용되는 리소스를 해방합니다.close를 호출할 때까지 명시적인 셧다운시퀀스를 발행하지 않으면 셧다운시퀀스가 시작됩니다.

"filescriptor()는 실제로 파일 기술자를 닫는 것이 아니라 사용성을 변경할 뿐입니다.소켓 기술자를 해방하려면 close()를 사용해야 합니다."1

linux:shutdown()을 지정하면 리스너 스레드 선택()이 활성화되어 오류가 발생합니다.shutdown(); close(); 끝없는 대기 상태가 됩니다.

winsock: 반대의 경우 - shutdown()은 효과가 없지만 close()는 정상적으로 캐치됩니다.

내 시험에서.

close소켓이 다른 프로세스와 공유되지 않으면 fin 패킷을 전송하고 fd를 즉시 파기합니다.

shutdown SUT_RD, 프로세스는 소켓에서 데이터를 수신할 수 있지만recvTCP 버퍼가 비어 있으면0 을 반환합니다.피어(peer)가 더 많은 데이터를 전송한 후recv데이터가 다시 반환됩니다.

shutdown SUT_WR은 추가 전송이 허용되지 않음을 나타내는 fin 패킷을 보냅니다.피어는 데이터를 수신할 수 있지만 TCP 버퍼가 비어 있는 경우 0을 수신합니다.

shutdown SUT_RDWR(SHUT_RDSHUT_WR을 모두 사용하는 것과 동일)은 피어가 더 많은 데이터를 전송하면 rst 패킷을 전송합니다.

가까운.

소켓 사용이 끝나면 파일 기술자를 닫기만 하면 됩니다.접속을 통해 전송 대기 중인 데이터가 있는 경우 보통 닫힘이 이 전송을 완료합니다.이 동작은 SO_LINGER 소켓옵션을 사용하여 타임아웃 기간을 지정할 수 있습니다.「소켓 옵션」을 참조해 주세요.

셧다운

또, shutdown을 호출하는 것으로, 접속의 수신 또는 송신만을 셧다운 할 수도 있습니다.

shutdown 기능은 소켓 연결을 차단합니다.이 인수는 수행할 액션을 지정하는 방법을 지정합니다.0 이 소켓에 대한 데이터 수신을 중지합니다.추가 데이터가 도착하면 거부합니다.1 이 소켓에서 데이터 전송을 중지합니다.전송 대기 중인 모든 데이터를 폐기합니다.이미 송신된 데이터의 확인 응답을 찾는 것을 중지합니다.분실했을 경우는 재발송하지 않습니다.2 수신과 송신을 모두 정지합니다.

반환값은 성공 시 0, 실패 시 -1입니다.

언급URL : https://stackoverflow.com/questions/4160347/close-vs-shutdown-socket

반응형