มีวิธีสำหรับหลายกระบวนการในการแชร์ซ็อกเก็ตการฟังหรือไม่?


90

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

สองกระบวนการไม่สามารถเชื่อมโยงกับพอร์ตเดียวกันในเวลาเดียวกัน - โดยค่าเริ่มต้นอย่างไรก็ตาม

ฉันสงสัยว่ามีวิธีใด (ในระบบปฏิบัติการที่รู้จักกันดีโดยเฉพาะ Windows) ในการเปิดใช้งานอินสแตนซ์หลาย ๆ ขั้นตอนเพื่อให้พวกเขาเชื่อมโยงกับซ็อกเก็ตทั้งหมดดังนั้นพวกเขาจึงแบ่งปันคิวได้อย่างมีประสิทธิภาพ จากนั้นแต่ละอินสแตนซ์ของกระบวนการสามารถเป็นเธรดเดียว มันจะบล็อกเมื่อยอมรับการเชื่อมต่อใหม่ เมื่อไคลเอ็นต์เชื่อมต่ออินสแตนซ์กระบวนการที่ไม่ได้ใช้งานตัวใดตัวหนึ่งจะยอมรับไคลเอ็นต์นั้น

สิ่งนี้จะช่วยให้แต่ละกระบวนการมีการใช้งานแบบเธรดเดียวที่เรียบง่ายมากโดยไม่ต้องแชร์อะไรเลยเว้นแต่ผ่านหน่วยความจำที่แบ่งใช้อย่างชัดเจนและผู้ใช้จะสามารถปรับแบนด์วิดท์การประมวลผลได้โดยเริ่มอินสแตนซ์เพิ่มเติม

คุณสมบัติดังกล่าวมีอยู่จริงหรือไม่?

แก้ไข:สำหรับผู้ที่ถามว่า "ทำไมไม่ใช้เธรด" เห็นได้ชัดว่าเธรดเป็นตัวเลือก แต่ด้วยหลายเธรดในกระบวนการเดียวอ็อบเจ็กต์ทั้งหมดสามารถแชร์ได้และต้องใช้ความระมัดระวังเป็นอย่างยิ่งเพื่อให้แน่ใจว่าอ็อบเจ็กต์ไม่ได้ถูกแชร์หรือมองเห็นได้ทีละเธรดเท่านั้นหรือไม่เปลี่ยนรูปอย่างแน่นอนและเป็นภาษายอดนิยมและ เวลาทำงานขาดการสนับสนุนในตัวสำหรับการจัดการความซับซ้อนนี้

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


2
ฉันยอมรับกระบวนการที่หลากหลายสามารถช่วยให้สร้างการใช้งานที่ถูกต้องและมีประสิทธิภาพได้ง่ายขึ้น ปรับขนาดได้ฉันไม่แน่ใจขึ้นอยู่กับโดเมนปัญหาของคุณ
MarkR

คำตอบ:


92

คุณสามารถแชร์ซ็อกเก็ตระหว่างสองกระบวนการ (หรือมากกว่า) ใน Linux และแม้แต่ Windows

ภายใต้ Linux (หรือระบบปฏิบัติการประเภท POSIX) การใช้fork()จะทำให้ลูกที่ถูกแยกมีสำเนาของตัวอธิบายไฟล์ของผู้ปกครองทั้งหมด สิ่งใดก็ตามที่ไม่ปิดจะถูกแชร์ต่อไปและ (ตัวอย่างเช่นกับซ็อกเก็ตการฟัง TCP) สามารถใช้กับaccept()ซ็อกเก็ตใหม่สำหรับไคลเอนต์ได้ นี่คือจำนวนเซิร์ฟเวอร์รวมถึง Apache ในกรณีส่วนใหญ่ใช้งานได้

ใน Windows สิ่งเดียวกันนั้นเป็นจริงโดยทั่วไปยกเว้นไม่มีการfork()เรียกระบบดังนั้นกระบวนการหลักจะต้องใช้CreateProcessหรือบางสิ่งบางอย่างเพื่อสร้างกระบวนการลูก (ซึ่งแน่นอนว่าสามารถใช้ปฏิบัติการเดียวกันได้) และจำเป็นต้องส่งตัวจัดการที่สืบทอดได้

การสร้างซ็อกเก็ตการฟังที่จับที่สืบทอดได้นั้นไม่ใช่กิจกรรมที่ไม่สำคัญ แต่ก็ไม่ใช่เรื่องยุ่งยากเกินไป DuplicateHandle()จำเป็นต้องใช้เพื่อสร้างจุดจับที่ซ้ำกัน (ยังคงอยู่ในกระบวนการหลัก) ซึ่งจะมีการตั้งค่าสถานะที่สืบทอดได้ จากนั้นคุณสามารถให้จับในที่STARTUPINFOโครงสร้างกระบวนการเด็กใน CreateProcess เป็นSTDIN, OUTหรือERRการจัดการ (สมมติว่าคุณไม่ต้องการที่จะใช้มันสำหรับสิ่งอื่น)

แก้ไข:

เมื่ออ่านไลบรารี MDSN ดูเหมือนว่าWSADuplicateSocketเป็นกลไกที่แข็งแกร่งหรือถูกต้องกว่าในการทำเช่นนี้ ยังคงเป็นเรื่องไม่สำคัญเนื่องจากกระบวนการแม่ / ลูกจำเป็นต้องค้นหาว่าหมายเลขอ้างอิงใดที่ต้องทำซ้ำโดยกลไก IPC บางอย่าง (แม้ว่าจะทำได้ง่ายเหมือนไฟล์ในระบบไฟล์ก็ตาม)

การจำแนก:

ในการตอบคำถามเดิม OP ที่ไม่มีกระบวนการหลายไม่สามารถbind(); เพียงแค่การปกครองเดิมจะเรียกbind(), listen()ฯลฯ กระบวนการที่เด็กก็จะดำเนินการตามคำขอโดยaccept(), send(), recv()ฯลฯ


3
หลายกระบวนการสามารถผูกโดยการระบุอ็อพชันซ็อกเก็ต SocketOptionName.ReuseAddress
Aaron Clauson

แต่ประเด็นคืออะไร? กระบวนการมีน้ำหนักมากกว่าเธรดอยู่แล้ว
Anton Tykhyy

7
กระบวนการมีน้ำหนักมากกว่าเธรด แต่เนื่องจากแชร์เฉพาะสิ่งที่แชร์อย่างชัดเจนจึงจำเป็นต้องมีการซิงโครไนซ์น้อยลงซึ่งทำให้การเขียนโปรแกรมง่ายขึ้นและอาจมีประสิทธิภาพมากขึ้นในบางกรณี
MarkR

11
ยิ่งไปกว่านั้นหากกระบวนการย่อยขัดข้องหรือหยุดชะงักไม่ทางใดก็ทางหนึ่งก็มีโอกาสน้อยที่จะส่งผลกระทบต่อผู้ปกครอง
MarkR

4
นอกจากนี้โปรดทราบว่าใน linux คุณสามารถ "ส่งต่อ" ซ็อกเก็ตไปยังโปรแกรมอื่นได้โดยไม่ต้องใช้ fork () และไม่มีความสัมพันธ์ระหว่างแม่ / ลูกโดยใช้ Unix Sockets
Rahly

35

คนอื่น ๆ ส่วนใหญ่ให้เหตุผลทางเทคนิคว่าทำไมจึงได้ผล นี่คือรหัสหลามที่คุณสามารถเรียกใช้เพื่อสาธิตสิ่งนี้ด้วยตัวคุณเอง:

import socket
import os

def main():
    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serversocket.bind(("127.0.0.1", 8888))
    serversocket.listen(0)

    # Child Process
    if os.fork() == 0:
        accept_conn("child", serversocket)

    accept_conn("parent", serversocket)

def accept_conn(message, s):
    while True:
        c, addr = s.accept()
        print 'Got connection from in %s' % message
        c.send('Thank you for your connecting to %s\n' % message)
        c.close()

if __name__ == "__main__":
    main()

โปรดทราบว่ามีการฟังรหัสกระบวนการสองรายการ:

$ lsof -i :8888
COMMAND   PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Python  26972 avaitla    3u  IPv4 0xc26aa26de5a8fc6f      0t0  TCP localhost:ddi-tcp-1 (LISTEN)
Python  26973 avaitla    3u  IPv4 0xc26aa26de5a8fc6f      0t0  TCP localhost:ddi-tcp-1 (LISTEN)

นี่คือผลลัพธ์จากการเรียกใช้ telnet และโปรแกรม:

$ telnet 127.0.0.1 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Thank you for your connecting to parent
Connection closed by foreign host.
$ telnet 127.0.0.1 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Thank you for your connecting to child
Connection closed by foreign host.
$ telnet 127.0.0.1 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Thank you for your connecting to parent
Connection closed by foreign host.

$ python prefork.py 
Got connection from in parent
Got connection from in child
Got connection from in parent

2
ดังนั้นสำหรับการเชื่อมต่อเดียวทั้งผู้ปกครองหรือเด็กจะได้รับ แต่ผู้ที่ได้รับการเชื่อมต่อนั้นไม่แน่นอนใช่มั้ย?
Hot.PxL

1
ใช่ฉันคิดว่ามันขึ้นอยู่กับกระบวนการที่ระบบปฏิบัติการกำหนดไว้
Anil Vaitla

14

ฉันต้องการเพิ่มว่าสามารถแชร์ซ็อกเก็ตบน Unix / Linux ผ่านซ็อกเก็ต AF__UNIX (ซ็อกเก็ตระหว่างกระบวนการ) สิ่งที่ดูเหมือนจะเกิดขึ้นคือตัวอธิบายซ็อกเก็ตใหม่ถูกสร้างขึ้นซึ่งเป็นนามแฝงของชื่อเดิม ตัวอธิบายซ็อกเก็ตใหม่นี้ถูกส่งผ่านซ็อกเก็ต AFUNIX ไปยังกระบวนการอื่น สิ่งนี้มีประโยชน์อย่างยิ่งในกรณีที่กระบวนการไม่สามารถแยก () เพื่อแบ่งปันคำอธิบายไฟล์ได้ ตัวอย่างเช่นเมื่อใช้ไลบรารีที่ป้องกันไม่ให้เกิดปัญหานี้เนื่องจากปัญหาเธรด คุณควรสร้างซ็อกเก็ตโดเมน Unix และใช้libancillaryเพื่อส่งผ่าน descriptor

ดู:

สำหรับการสร้าง AF_UNIX Sockets:

ตัวอย่างรหัส:


13

ดูเหมือนว่าคำถามนี้ได้รับคำตอบอย่างครบถ้วนจาก MarkR และ zackthehack แต่ฉันอยากจะเพิ่มว่า Nginx เป็นตัวอย่างของการสืบทอดซ็อกเก็ตการฟัง

นี่คือคำอธิบายที่ดี:

         Implementation of HTTP Auth Server Round-Robin and
                Memory Caching for NGINX Email Proxy

                            June 6, 2007
             Md. Mansoor Peerbhoy <mansoor@zimbra.com>

...

ขั้นตอนของกระบวนการทำงานของ NGINX

หลังจากกระบวนการ NGINX หลักอ่านไฟล์คอนฟิกูเรชันและแยกเข้าสู่จำนวนกระบวนการของผู้ปฏิบัติงานที่กำหนดค่าไว้กระบวนการของผู้ปฏิบัติงานแต่ละคนจะเข้าสู่ลูปที่รอเหตุการณ์ใด ๆ บนชุดซ็อกเก็ตที่เกี่ยวข้อง

กระบวนการของผู้ปฏิบัติงานแต่ละคนเริ่มต้นด้วยซ็อกเก็ตการฟังเท่านั้นเนื่องจากยังไม่มีการเชื่อมต่อ ดังนั้นตัวอธิบายเหตุการณ์ที่ตั้งไว้สำหรับแต่ละกระบวนการของผู้ปฏิบัติงานเริ่มต้นด้วยซ็อกเก็ตการฟังเท่านั้น

(หมายเหตุ) สามารถกำหนดค่า NGINX ให้ใช้กลไกการสำรวจเหตุการณ์อย่างใดอย่างหนึ่ง: aio / devpoll / epoll / eventpoll / kqueue / โพล / rtsig / select

เมื่อการเชื่อมต่อมาถึงซ็อกเก็ตการฟังใด ๆ (POP3 / IMAP / SMTP) กระบวนการของผู้ปฏิบัติงานแต่ละคนจะปรากฏขึ้นจากแบบสำรวจเหตุการณ์เนื่องจากกระบวนการของผู้ปฏิบัติงาน NGINX แต่ละกระบวนการสืบทอดซ็อกเก็ตการฟัง จากนั้นกระบวนการของพนักงาน NGINX แต่ละคนจะพยายามได้รับ mutex ระดับโลก หนึ่งในกระบวนการของผู้ปฏิบัติงานจะได้รับการล็อกในขณะที่กระบวนการอื่น ๆ จะกลับไปที่ลูปการสำรวจเหตุการณ์ตามลำดับ

ในขณะเดียวกันกระบวนการของผู้ปฏิบัติงานที่ได้รับ global mutex จะตรวจสอบเหตุการณ์ที่ถูกทริกเกอร์และจะสร้างคำขอคิวงานที่จำเป็นสำหรับแต่ละเหตุการณ์ที่ถูกทริกเกอร์ เหตุการณ์สอดคล้องกับตัวบอกซ็อกเก็ตเดียวจากชุดตัวอธิบายที่ผู้ปฏิบัติงานกำลังเฝ้าดูเหตุการณ์

หากเหตุการณ์ที่ถูกทริกเกอร์สอดคล้องกับการเชื่อมต่อขาเข้าใหม่ NGINX ยอมรับการเชื่อมต่อจากซ็อกเก็ตการฟัง จากนั้นเชื่อมโยงโครงสร้างข้อมูลบริบทกับ file descriptor บริบทนี้เก็บข้อมูลเกี่ยวกับการเชื่อมต่อ (ไม่ว่าจะเป็น POP3 / IMAP / SMTP ผู้ใช้ยังได้รับการพิสูจน์ตัวตนหรือไม่ ฯลฯ ) จากนั้นซ็อกเก็ตที่สร้างขึ้นใหม่นี้จะถูกเพิ่มเข้าไปในชุดตัวบอกเหตุการณ์สำหรับกระบวนการของผู้ปฏิบัติงานนั้น

ขณะนี้ผู้ปฏิบัติงานได้ยกเลิก mutex (ซึ่งหมายความว่าเหตุการณ์ใด ๆ ที่มาถึงคนงานคนอื่นสามารถพิสูจน์ได้) และเริ่มประมวลผลคำขอแต่ละรายการที่อยู่ในคิวก่อนหน้านี้ แต่ละคำขอสอดคล้องกับเหตุการณ์ที่ส่งสัญญาณ จากตัวบอกซ็อกเก็ตแต่ละตัวที่ถูกส่งสัญญาณกระบวนการของผู้ปฏิบัติงานจะดึงโครงสร้างข้อมูลบริบทที่เกี่ยวข้องซึ่งก่อนหน้านี้เชื่อมโยงกับตัวอธิบายนั้นจากนั้นเรียกใช้ฟังก์ชันเรียกกลับที่เกี่ยวข้องซึ่งดำเนินการตามสถานะของการเชื่อมต่อนั้น ตัวอย่างเช่นในกรณีของการเชื่อมต่อ IMAP ที่สร้างขึ้นใหม่สิ่งแรกที่ NGINX จะทำคือการเขียนข้อความต้อนรับ IMAP มาตรฐานลงใน
ซ็อกเก็ตที่เชื่อมต่อ (* OK IMAP4 ready)

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


11

ไม่แน่ใจว่าสิ่งนี้เกี่ยวข้องกับคำถามเดิมแค่ไหน แต่ใน Linux kernel 3.9 มีโปรแกรมแก้ไขที่เพิ่มคุณสมบัติ TCP / UDP: รองรับ TCP และ UDP สำหรับตัวเลือกซ็อกเก็ต SO_REUSEPORT ตัวเลือกซ็อกเก็ตใหม่ช่วยให้หลายซ็อกเก็ตบนโฮสต์เดียวกันสามารถเชื่อมโยงกับพอร์ตเดียวกันและมีจุดมุ่งหมายเพื่อปรับปรุงประสิทธิภาพของแอพพลิเคชั่นเซิร์ฟเวอร์เครือข่ายแบบมัลติเธรดที่ทำงานบนระบบมัลติคอร์ สามารถดูข้อมูลเพิ่มเติมได้ในลิงค์LWN LWN SO_REUSEPORT ใน Linux Kernel 3.9ตามที่กล่าวไว้ในลิงค์อ้างอิง:

ตัวเลือก SO_REUSEPORT ไม่ใช่มาตรฐาน แต่มีอยู่ในรูปแบบที่คล้ายกันในระบบ UNIX อื่น ๆ จำนวนมาก (โดยเฉพาะอย่างยิ่ง BSD ซึ่งเป็นจุดเริ่มต้นของแนวคิด) ดูเหมือนว่าจะเป็นทางเลือกที่มีประโยชน์ในการบีบประสิทธิภาพสูงสุดออกจากแอปพลิเคชันเครือข่ายที่ทำงานบนระบบมัลติคอร์โดยไม่ต้องใช้รูปแบบส้อม


จากบทความ LWN ดูเหมือนว่าSO_REUSEPORTจะสร้างพูลเธรดโดยที่แต่ละซ็อกเก็ตอยู่บนเธรดที่แตกต่างกัน แต่มีเพียงซ็อกเก็ตเดียวในกลุ่มเท่านั้นที่ดำเนินการaccept. คุณสามารถยืนยันซ็อกเก็ตทั้งหมดในกลุ่มได้รับสำเนาข้อมูลหรือไม่
jww

4

เริ่มต้นด้วย Linux 3.9 คุณสามารถตั้งค่า SO_REUSEPORT บนซ็อกเก็ตจากนั้นให้กระบวนการที่ไม่เกี่ยวข้องหลายอย่างแชร์ซ็อกเก็ตนั้น ง่ายกว่าโครงร่าง prefork ไม่มีปัญหาสัญญาณอีกต่อไป fd รั่วไหลไปยังกระบวนการย่อย ฯลฯ

Linux 3.9 เปิดตัววิธีใหม่ในการเขียนซ็อกเก็ตเซิร์ฟเวอร์

ตัวเลือกซ็อกเก็ต SO_REUSEPORT


3

มีงานเดียวที่มีงานเดียวคือรับฟังการเชื่อมต่อที่เข้ามา เมื่อได้รับการเชื่อมต่อจะยอมรับการเชื่อมต่อซึ่งจะสร้างตัวบอกซ็อกเก็ตแยกต่างหาก ซ็อกเก็ตที่ได้รับการยอมรับจะถูกส่งผ่านไปยังงานของผู้ปฏิบัติงานที่มีอยู่ของคุณและงานหลักจะกลับไปที่การรับฟัง

s = socket();
bind(s);
listen(s);
while (1) {
  s2 = accept(s);
  send_to_worker(s2);
}

ซ็อกเก็ตส่งผ่านไปยังคนงานได้อย่างไร? โปรดจำไว้ว่าแนวคิดคือคนงานเป็นกระบวนการที่แยกจากกัน
Daniel Earwicker

ส้อม () บางทีหรือแนวคิดอื่น ๆ ข้างต้น หรือบางทีคุณอาจแยกซ็อกเก็ต I / O ออกจากการประมวลผลข้อมูลโดยสิ้นเชิง ส่งข้อมูลไปยังกระบวนการของผู้ปฏิบัติงานผ่านกลไก IPC OpenSSH และเครื่องมือ OpenBSD อื่น ๆ ใช้วิธีการนี้ (ไม่มีเธรด)
HUAGHAGUAH

3

ภายใต้ Windows (และ Linux) เป็นไปได้ที่กระบวนการหนึ่งจะเปิดซ็อกเก็ตแล้วส่งต่อซ็อกเก็ตนั้นไปยังกระบวนการอื่นเพื่อให้กระบวนการที่สองนั้นสามารถใช้ซ็อกเก็ตนั้นได้ (และส่งต่อไปในทางกลับกันหากต้องการทำเช่นนั้น) .

การเรียกใช้ฟังก์ชันที่สำคัญคือ WSADuplicateSocket ()

สิ่งนี้จะเติมโครงสร้างด้วยข้อมูลเกี่ยวกับซ็อกเก็ตที่มีอยู่ โครงสร้างนี้ผ่านกลไก IPC ที่คุณเลือกจะถูกส่งผ่านไปยังกระบวนการอื่นที่มีอยู่ (โปรดทราบว่ามีอยู่ - เมื่อคุณเรียกใช้ WSADuplicateSocket () คุณต้องระบุกระบวนการเป้าหมายซึ่งจะได้รับข้อมูลที่ปล่อยออกมา)

จากนั้นกระบวนการรับสามารถเรียก WSASocket () ส่งผ่านโครงสร้างข้อมูลนี้และรับหมายเลขอ้างอิงไปยังซ็อกเก็ตที่อยู่ภายใต้

ขณะนี้กระบวนการทั้งสองถือที่จับเข้ากับซ็อกเก็ตที่อยู่ข้างใต้เดียวกัน


2

ดูเหมือนว่าสิ่งที่คุณต้องการคือกระบวนการหนึ่งที่รับฟังลูกค้าใหม่จากนั้นจึงทำการปิดการเชื่อมต่อเมื่อคุณได้รับการเชื่อมต่อ การทำเช่นนั้นข้ามเธรดเป็นเรื่องง่ายและใน. Net คุณยังมีวิธีการ BeginAccept เป็นต้นเพื่อดูแลท่อประปาจำนวนมากสำหรับคุณ ในการส่งต่อการเชื่อมต่อข้ามขอบเขตของกระบวนการจะมีความซับซ้อนและไม่มีข้อได้เปรียบด้านประสิทธิภาพใด ๆ

หรือคุณสามารถมีหลายกระบวนการที่ผูกไว้และฟังบนซ็อกเก็ตเดียวกัน

TcpListener tcpServer = new TcpListener(IPAddress.Loopback, 10090);
tcpServer.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
tcpServer.Start();

while (true)
{
    TcpClient client = tcpServer.AcceptTcpClient();
    Console.WriteLine("TCP client accepted from " + client.Client.RemoteEndPoint + ".");
}

หากคุณเริ่มต้นสองกระบวนการโดยแต่ละกระบวนการเรียกใช้รหัสข้างต้นมันจะทำงานได้และกระบวนการแรกดูเหมือนจะได้รับการเชื่อมต่อทั้งหมด หากกระบวนการแรกถูกฆ่ากระบวนการที่สองจะได้รับการเชื่อมต่อ ด้วยการแชร์ซ็อกเก็ตเช่นนั้นฉันไม่แน่ใจว่า Windows ตัดสินใจอย่างไรว่ากระบวนการใดจะได้รับการเชื่อมต่อใหม่แม้ว่าการทดสอบอย่างรวดเร็วจะชี้ไปที่กระบวนการที่เก่าที่สุดในการเริ่มต้นก่อน ว่ามันจะแชร์ถ้ากระบวนการแรกยุ่งหรืออะไรอย่างนั้นฉันไม่รู้


2

อีกวิธีหนึ่ง (ที่หลีกเลี่ยงรายละเอียดที่ซับซ้อนมากมาย) ใน Windows หากคุณใช้ HTTP คือการใช้ HTTP.SYS ซึ่งช่วยให้กระบวนการต่างๆสามารถรับฟัง URL ที่แตกต่างกันบนพอร์ตเดียวกันได้ บนเซิร์ฟเวอร์ 2003/2008 / Vista / 7 นี่คือวิธีการทำงานของ IIS ดังนั้นคุณสามารถแชร์พอร์ตกับมันได้ (บน XP SP2 HTTP.SYS ได้รับการสนับสนุน แต่ IIS5.1 ไม่ได้ใช้งาน)

API ระดับสูงอื่น ๆ (รวมถึง WCF) ใช้ HTTP.SYS

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