พอร์ตต้นทางของ TCP ต้องไม่ซ้ำกันสำหรับแต่ละโฮสต์หรือไม่


10

ฉันได้เรียนรู้ว่าการเชื่อมต่อ TCP ถูกระบุโดย tuple (IP ต้นทาง, พอร์ตต้นทาง, ปลายทาง IP, พอร์ตปลายทาง) ในทางทฤษฎีแล้วมันควรจะเป็นไปได้ที่จะมีไคลเอนต์จาก host1: พอร์ต 1 เชื่อมต่อกับเซิร์ฟเวอร์ 1: พอร์ต 1 และในเวลาเดียวกันไคลเอนต์อื่น (ทำงานบนโฮสต์ 1) จากโฮสต์ 1: พอร์ต 1 ถึงเซิร์ฟเวอร์ 2: พอร์ต 1

ฉันได้ทำการทดสอบกับ Java แล้วและดูเหมือนว่าจะเป็นไปได้

อย่างไรก็ตามฉันได้อ่านหลาย ๆ ครั้งว่าพอร์ตต้นทางนั้นต้องไม่ซ้ำกันสำหรับที่อยู่โฮสต์ซึ่งโดยทั่วไปจะหมายความว่ามีขีด จำกัด สูงสุดที่การเชื่อมต่อ TCP ขาออกพร้อมกัน 65536 ส่วนใหญ่ มันเป็นเรื่องจริงเหรอ?

อัปเดต: นี่คือรหัส Java ของฉัน ดูเหมือนว่าจะใช้งานได้และ netstat -t แสดงการเชื่อมต่อที่ใช้งานอยู่สองขาออกจากพอร์ต 9990 อย่างชัดเจน(หนึ่งถึง 9997, หนึ่งถึง 9998) อย่างน้อยใน Linux ที่ทันสมัยดูเหมือนว่าจะเป็นไปได้?

Socket s1 = new Socket();
s1.setReuseAddress(true);
SocketAddress saremote = new InetSocketAddress("localhost",9999);
SocketAddress salocal = new InetSocketAddress("localhost",9990);
s1.bind(salocal);
s1.connect(saremote);


Socket s2 = new Socket();
s2.setReuseAddress(true);
SocketAddress saremote2 = new InetSocketAddress("localhost",9998);
SocketAddress salocal2 = new InetSocketAddress("localhost",9990);
s2.bind(salocal2);
s2.connect(saremote2);

และเอาต์พุต netstat -t (ตัดปลาย):

tcp6       0      0 localhost:9990          localhost:9998          CONNECTED 
tcp6       0      0 localhost:9990          localhost:9999          CONNECTED 

"ถ้าคุณถามถึงขีด จำกัด สูงสุดของระบบที่ออกแบบมาอย่างดีคุณก็เกือบจะทำได้อย่างแน่นอน"
Chris S

คำตอบ:


16

ไม่ใช่ข้อกำหนด TCP เท่าที่เกี่ยวข้องกับ TCP เฉพาะการรวมกันของ IP ต้นทางพอร์ตต้นทาง IP ปลายทางและพอร์ตปลายทางต้องไม่ซ้ำกัน อย่างไรก็ตามในทางปฏิบัติ TCP APIs ส่วนใหญ่ไม่มีวิธีใด ๆ ในการสร้างการเชื่อมต่อมากกว่าหนึ่งพอร์ตด้วยพอร์ตต้นทางเดียวกันยกเว้นว่าจะมีที่อยู่ IP ของแหล่งข้อมูลที่แตกต่างกัน


2
ขอบคุณที่ตอบคำถามเชิงทฤษฎีของคำถามทั้งหมด! ฉันจะต้องลองทุก ๆ การติดตั้ง TCP ฉันเดา
lxgr

5

นั่นเป็นค่าสูงสุดในการฝึกฝนซึ่งมักจะต่ำกว่า ตัวอย่างเช่น Linux ใช้net.ipv4.ip_local_portพารามิเตอร์เคอร์เนลเพื่อกำหนดพอร์ตที่ใช้สำหรับการเชื่อมต่อขาออก โดยปกติจะเป็นแบบนี้

sysctl net.ipv4.ip_local_port_range 32768 to 61000

คุณสามารถเพิ่มจำนวนที่มีอยู่ด้วย sysctl เช่น

sysctl -w net.ipv4.ip_local_port_range="10000 64000"

หรือคุณสามารถแก้ไข /etc/sysctl.conf ด้วยข้อมูลเดียวกัน

net.ipv4.ip_local_port_range = 10000 65535

ตัวอย่างทั้งหมดที่ฉันพบแสดงค่าต่ำสุดที่ 1024 เช่นกัน


1

นอกเหนือจากคำตอบของ Iain (ด้านบน) ว่าอาจมี 10,000 พอร์ตที่อนุญาตให้ใช้สำหรับการเชื่อมต่อขาออกโดยเคอร์เนลในทางทฤษฎีของคุณอย่างน้อยก็ จำกัด ไว้ที่ XX, XXX พอร์ตหนึ่งชุดต่อที่อยู่ IP ของอะแดปเตอร์ เนื่องจาก 127.1 ไม่สามารถใช้งานได้กับโลกภายนอกการอยู่บนเครือข่ายท้องถิ่นจากนั้นสำหรับที่อยู่ IP แต่ละแห่ง ( ภายนอก ) คุณจึงมีชุดของพอร์ตขาออกภายในช่วงพอร์ต 65K ของคุณ

ดังนั้นขีด จำกัด ขาออกจึงเป็นจริง:

  With 1 IP Address: XX,XXX (or 2 x XX,XXX on internal network)
  With 2 IP addresses: 2 x XX,XXX (or 3 x XX,XXX on internal network)
  With 3 IP addresses: 3 x XX,XXX (or 4 x XX,XXX on internal network)
  etc.

เพื่อให้งานนี้คุณจะต้องอ่านคำตอบของหัวข้อนี้


0

ใช่. นี่เป็นเรื่องจริง

พอร์ตจะผูกและแอพกับเครือข่าย

คุณไม่สามารถมีแอปพลิเคชันมากกว่า 65553 เชื่อมต่อโดย TCP และ 65535 เชื่อมต่อโดย UDP บนโฮสต์เดียวกัน ระบบปฏิบัติการได้จัดการพอร์ตที่กำหนดไว้สำหรับแต่ละแอพที่เชื่อมต่อกับเครือข่าย

หากคุณมีแอปพลิเคชั่นสองรายการที่พอร์ตเดียวกันเมื่อแพ็คเกจเครือข่ายมาถึงคอมพิวเตอร์จะไม่ทราบว่าแอปใดกำลังส่งข้อมูล ตัวอย่างเช่นหากคุณมี Messenger และ Skype บนพอร์ตเดียวกันกับพอร์ตเดียวกันข้อความ Messenger ของคุณจะปรากฏใน skype และในทางกลับกัน :)


ฉันคิดว่าคำถามนั้นไม่ได้เกี่ยวกับขีด จำกัด สูงสุดของจำนวนแอพพลิเคชั่นการฟัง - ซึ่งในขณะที่คุณชี้ให้เห็นจะถูก จำกัด ด้วยหมายเลขพอร์ตที่ไม่ซ้ำกัน - แต่เกี่ยวกับจำนวนซ็อกเก็ตที่ทำงานในเวลาเดียวกัน เว็บเซิร์ฟเวอร์มักจะมีซ็อกเก็ตหลายสิบตัวที่ส่งไปยังพอร์ตเดียว 80 หรือ 443 ถ้าเซิร์ฟเวอร์จำนวนมากในโฮสต์ทำเช่นนั้นก็ไม่มีเหตุผลว่าจำนวนซ็อกเก็ตเปิดไม่เกิน 2 ^ 32
Brandon Rhodes

0

แม้ว่าระบบอาจมีข้อ จำกัด เกี่ยวกับจำนวนการเชื่อมต่อ TCP แบบเปิด แต่โดยทั่วไปจะไม่มีข้อ จำกัด เกี่ยวกับหมายเลขพอร์ตที่ใช้ การใช้ TCP ที่ดีจะต้องป้องกันไม่ให้ใช้ซ็อกเก็ตคู่เดียวกันสองครั้ง (socket = ที่อยู่ IP + พอร์ต) อย่างไรก็ตามพอร์ตถูกกำหนดให้กับกระบวนการเพื่อป้องกันการขโมยการเชื่อมต่อและวิธีการปกติคือการร้องขอพอร์ตว่างสำหรับพอร์ตการฟังหรือพอร์ตขาออก สิ่งนี้จะช่วยป้องกันซ็อกเก็ตขาออกที่ซ้ำกันและการเชื่อมต่อที่ซ้ำซ้อน ล้มเหลวในการใช้วิธีการนั้นแอปพลิเคชันจะต้องป้องกันการสร้างการเชื่อมต่อที่ซ้ำกัน


3
สิ่งนี้จะเพิ่มสิ่งใดใหม่คำตอบที่โพสต์แล้วในคำถามเก่านี้ได้อย่างไร
Chris S
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.