在Mac OS X上,我的TIME_WAIT在哪里?


9

TIME_WAIT在Mac OS X上为否

通常,当关闭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

测试中

这是Python中的两个简单测试程序。

服务器

#!/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预期的a:

$ ./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运行时看不到a netstat -an | grep 50007


好问题。我自己看到的是同一件事,没有看到netstat包含它们的任何选择……
natevw 2014年

2
FWIW,sudo lsof -i -P对于已退出的进程都不显示TIME_WAIT状态。
natevw 2014年

@natevw很高兴知道我并不孤单。:-)
mgd 2014年

Answers:


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 !?谁发回此数据包?服务器进程已关闭!” 它似乎是由处于TIME_WAIT状态的服务器发送的,因为它是发送第一个FIN的部分。即使服务器进程已终止,TCP堆栈仍保持连接状态以发送最后一个ACK。
neverov '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.