TIME_WAIT ของฉันอยู่ที่ไหนใน Mac OS X


9

ไม่มีTIME_WAITใน Mac OS X

โดยปกติเมื่อปิดการเชื่อมต่อ TCP ซ็อกเก็ตด้านข้างที่close()เรียกว่าครั้งแรกจะถูกทิ้งให้อยู่ในTIME_WAITสถานะ

เมื่อเพื่อนคนหนึ่งเป็นเครื่อง Mac OS X (Lion) TIME_WAITจะไม่มีรายชื่ออยู่netstat -anบน Mac หากclose()มีการเรียกครั้งแรกทางด้าน Mac อย่างไรก็ตามดูเหมือนว่าซ็อกเก็ตอยู่ในTIME_WAITสถานะจริงเนื่องจากพยายามโทรlisten()อีกครั้ง (โดยไม่ใช้ตัวเลือกซ็อกเก็ตSO_REUSEADDR) ทำให้listen()ล้มเหลว

กำลังรอ 2 * MSL (อายุการใช้งานส่วนสูงสุดซึ่งคือ 15 วินาทีบน Mac OS X Lion ตามที่รายงานโดย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ตามที่คาดไว้:

$ ./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) ฉันไม่เคยเห็นTIME_WAITเมื่อทำงานnetstat -an | grep 50007หลังจากปิดก่อนบน Mac


คำถามที่ดี. เห็นสิ่งเดียวกันตัวเองและไม่เห็นตัวเลือกใด ๆ ที่ 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; }

เพื่อให้มันแสดงซ็อกเก็ตที่ถูกผูกไว้กับ localhost


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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.