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.