Mac OS X에서 TIME_WAIT는 어디에 있습니까?


9

TIME_WAITMac OS X에 s 없음

일반적으로 TCP 연결이 닫히면 close()처음 호출 되는 쪽의 소켓 이 TIME_WAIT상태로 유지됩니다.

피어 중 하나가 Mac OS X (Lion) 시스템 인 경우 Mac 측에서 먼저 호출 된 경우 Mac에 아무 TIME_WAIT것도 표시 되지 않습니다 . 그러나 소켓 옵션을 사용하지 않고 다시 호출 하면 실패 하기 때문에 소켓 이 실제로 상태에 있는 것 같습니다 .netstat -anclose()TIME_WAITlisten()SO_REUSEADDRlisten()

2 * MSL (Mac OS X Lion에서보고 한 최대 세그먼트 수명 15 초) 동안 대기 sysctl net.inet.tcp.msl하면 TIME_WAIT상태가 지워지고 listen()오류없이 다시 호출 할 수 있습니다.

소켓이 보이지 않는 이유는 무엇 TIME_WAIT입니까?

테스팅

다음은 파이썬에서 간단한 두 가지 테스트 프로그램입니다.

섬기는 사람

#!/usr/bin/env python

import socket

HOST = ''
PORT = 50007
l = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
l.bind((HOST, PORT))
l.listen(1)
print("Listening on %d" % PORT)
(s, _) = l.accept()
print("Connected")
raw_input("Press <enter> to close...")
l.close()
s.close()
print("Closed")

고객

#!/usr/bin/env python

import socket
import sys

HOST = sys.argv[1]
PORT = 50007

print("Opening connection to server")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
raw_input("Press <enter> to close...")
s.close()
print("Closed")

두 개의 다른 Linux 시스템에서 서버와 클라이언트를 모두 실행하는 경우 먼저 <enter>호출 을 눌러 피어가 예상 한대로 close()가져 옵니다 TIME_WAIT.

$ ./server-timewait.py 
Listening on 50007
Connected
Press <enter> to close...
Closed
$ netstat -an | grep 50007
tcp        0      0 172.16.185.219:50007    172.16.185.42:49818     TIME_WAIT  
$ 

동료 중 하나가 Mac (OS X Lion 실행) 일 때 Mac에서 처음 닫은 후에 는 TIME_WAIT실행 되지 않습니다 netstat -an | grep 50007.


좋은 질문. netstat 옵션을 보지 않고 같은 것을 직접보고…
— natevw

2
FWIW sudo lsof -i -P는 이미 종료 된 프로세스에 대해 TIME_WAIT 상태를 표시하지 않습니다.
— natevw

@natevw 나는 혼자가 아니라는 것을 알게되어 기쁘다. :-)
— mgd

답변:


2

이 버그 보고서 는 문제가 netstat 구현 에 있다고 주장합니다 . 버그 보고서에 첨부 된 코드는 TIME_WAIT 상태의 소켓을 올바르게 표시합니다. 다음 줄을 제거해야합니다

if (lip == INADDR_LOCALHOST ||
  lip == INADDR_ANY
  ) { continue; }

로컬 호스트에 바인딩 된 소켓을 표시합니다.


0

이것은 대답이 아니지만 누군가가 이것에서 더 많은 것을 파헤칠 수 있습니다.

tcpdump -i lo0 -vv port 50007

## Press Enter at the server window

# Server send a FIN (note the flag)
23:33:04.283768 IP (tos 0x0, ttl 64, id 4134, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->2c9c)!)
    localhost.50007 > localhost.56030: Flags [F.], cksum 0xfe28 (incorrect -> 0xeff9), seq 1, ack 1, win 9186, options [nop,nop,TS val 432165676 ecr 432157913], length 0

# Client send back ACK
23:33:04.283803 IP (tos 0x0, ttl 64, id 44906, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->8d57)!)
    localhost.56030 > localhost.50007: Flags [.], cksum 0xfe28 (incorrect -> 0xd1a6), seq 1, ack 2, win 9186, options [nop,nop,TS val 432165676 ecr 432165676], length 0

# Server confirm the ACK is received
23:33:04.283812 IP (tos 0x0, ttl 64, id 18284, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->f555)!)
    localhost.50007 > localhost.56030: Flags [.], cksum 0xfe28 (incorrect -> 0xd1a6), seq 2, ack 1, win 9186, options [nop,nop,TS val 432165676 ecr 432165676], length 0

## After this point, the server process is actually exit but client still running.
## It's strange that re-run server script gives "OSError: [Errno 48] Address already in use"
## and netstat shows this connection is in CLOSE_WAIT status

## Press Enter at the client window

# Client send a FIN to server
23:33:09.731728 IP (tos 0x0, ttl 64, id 51478, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->73ab)!)
    localhost.56030 > localhost.50007: Flags [F.], cksum 0xfe28 (incorrect -> 0xbcb6), seq 1, ack 2, win 9186, options [nop,nop,TS val 432171035 ecr 432165676], length 0

# WTH!? Who send back this packet? The server process is closed!
23:33:09.731764 IP (tos 0x0, ttl 64, id 18754, offset 0, flags [DF], proto TCP (6), length 52, bad cksum 0 (->f37f)!)
    localhost.50007 > localhost.56030: Flags [.], cksum 0xfe28 (incorrect -> 0xa7c7), seq 2, ack 2, win 9186, options [nop,nop,TS val 432171035 ecr 432171035], length 0

"WTH !?이 패킷을 누가 다시 보내나요? 서버 프로세스가 종료되었습니다!" 첫 번째 FIN을 보내는 부분이기 때문에 TIME_WAIT 상태 인 서버에서 보낸 것으로 보입니다. 서버 프로세스가 종료되었지만 TCP 스택은 마지막 ACK를 보내기 위해 연결 상태를 유지합니다.
— neverov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.