ฉันเข้าใจว่า "ทุกอย่างเป็นไฟล์" เป็นหนึ่งในแนวคิดหลักของ Unix แต่ซ็อกเก็ตใช้ API ที่แตกต่างกันซึ่งให้บริการโดยเคอร์เนล (เช่นซ็อกเก็ต, sendto, recv และอื่น ๆ ) ไม่เหมือนอินเทอร์เฟซระบบไฟล์ทั่วไป
"ทุกอย่างเป็นไฟล์" นำไปใช้ที่นี่ได้อย่างไร
ฉันเข้าใจว่า "ทุกอย่างเป็นไฟล์" เป็นหนึ่งในแนวคิดหลักของ Unix แต่ซ็อกเก็ตใช้ API ที่แตกต่างกันซึ่งให้บริการโดยเคอร์เนล (เช่นซ็อกเก็ต, sendto, recv และอื่น ๆ ) ไม่เหมือนอินเทอร์เฟซระบบไฟล์ทั่วไป
"ทุกอย่างเป็นไฟล์" นำไปใช้ที่นี่ได้อย่างไร
คำตอบ:
ซ็อกเก็ตใช้ API ที่ต่างกัน
นั่นไม่จริงทั้งหมด มีฟังก์ชั่นเพิ่มเติมบางอย่างสำหรับใช้กับซ็อกเก็ต แต่คุณสามารถใช้เช่นปกติread()
และwrite()
บนซ็อกเก็ต fd
"ทุกอย่างเป็นไฟล์" มีผลกับที่นี่อย่างไร
ในแง่ที่ว่าไฟล์ descriptor เกี่ยวข้อง
หากคำจำกัดความของคุณของ "file" เป็นลำดับไบต์ที่แยกกันเก็บไว้ในระบบไฟล์แสดงว่าไม่ใช่ทุกอย่างที่เป็นไฟล์ อย่างไรก็ตามหากคำจำกัดความของไฟล์ของคุณมีลักษณะคล้ายกันมากขึ้น - ท่อสำหรับข้อมูลเช่นการเชื่อมต่อ I / O - ดังนั้น "ทุกอย่างเป็นไฟล์" จะเริ่มมีความหมายมากขึ้น สิ่งเหล่านี้เกี่ยวข้องกับการเรียงลำดับไบต์อย่างหลีกเลี่ยงไม่ได้ แต่สิ่งที่มาจากหรือไปอาจแตกต่างกันตามบริบท
อย่างไรก็ตามมันไม่ได้ตั้งใจอย่างแท้จริง ภูตไม่ได้เป็นไฟล์ภูตเป็นกระบวนการ; แต่ถ้าคุณกำลังทำIPCวิธีการของคุณที่เกี่ยวข้องกับกระบวนการอื่นอาจลดลงโดยเอนทิตีสไตล์ไฟล์
"ทุกอย่างเป็นไฟล์" เป็นเพียงการกล่าวเกินจริง มันเป็นนวนิยายในปี 1970 และมันเป็นลักษณะเด่นหลักของระบบปฏิบัติการยูนิกซ์ แต่มันเป็นเพียงแนวคิดทางการตลาดไม่ใช่รากฐานที่แท้จริงของ UNIX เพราะเห็นได้ชัดว่าไม่เป็นความจริง มันไม่มีประโยชน์หรือมีเหตุผลที่จะปฏิบัติต่อทุกสิ่งเป็นไฟล์
CPU เป็นไฟล์หรือไม่ โปรแกรมของคุณอ่าน () ซีพียูเพื่อรับคำสั่งใหม่หรือไม่? แรมเป็นไฟล์หรือไม่ โปรแกรมของคุณอ่าน () เป็นไบต์ต่อไปหรือไม่?
ก่อนหน้านี้มีระบบปฏิบัติการหลายชนิดที่ให้หนึ่ง API สำหรับฟลอปปีดิสก์และ API ที่แตกต่างกันสำหรับฮาร์ดดิสก์ API ที่แตกต่างกันสำหรับเทปแม่เหล็กและ API ที่แตกต่างกันมากมายสำหรับเทอร์มินัลต่าง ๆ เป็นต้น ระบบเมนเฟรมของ IBM มีไฟล์ประเภทต่าง ๆ บนฮาร์ดดิสก์และมอบ API ที่แตกต่างให้คุณแต่ละคนเชื่อหรือไม่! ดังนั้น UNIX "มันเป็นวิธีการ" ของไฟล์พร้อมกับวิธีการ "stdin / stdout / stderr" ได้นำสิ่งที่เป็นนามธรรมมาสู่ผู้ใช้และโปรแกรมเมอร์
ด้วยเครือข่ายสิ่งที่เป็นนามธรรมนี้ก็ไม่ได้ผล และไม่มีอันตรายใด ๆ เพียงแค่ความสง่างามโดยรวมและความต่อเนื่องของระบบปฏิบัติการลดลงเล็กน้อย แต่มันได้ผล วันนี้คุณเห็นไฟล์ที่เรียกว่า/dev/myinternetz/www/google/com/tcp/80
ที่ใดก็ได้ในระบบของคุณ คุณสามารถเปิด () มันเขียนแบบสอบถาม () และอ่าน () คำตอบใน HTML ที่ดี? ไม่มี? นี่เป็นเพราะสิ่งนี้ "เป็นไฟล์" สิ่งที่เป็นนามธรรมไม่สะดวกสำหรับการโต้ตอบกับเครือข่าย มันจะไม่ทำงานได้ดีในทางปฏิบัติ กฎหมายของ abstractions รั่วไหลในการดำเนินการ
/dev/tcp/www.google.com/80
บางรุ่นทุบตีจะช่วยให้คุณเปิด ไม่ใช่ไฟล์จริง - ทุบตีเป็นเพียงแกล้งทำมัน
/dev/mem
หรือ/dev/kmem
ถ้าคุณต้องการ
Sockets เป็นไฟล์ คุณสามารถใช้read
และwrite
ในซ็อกเก็ต: พวกเขากำลังเทียบเท่ากับการเรียกrecv
และมีsend
คุณปิดพวกเขาด้วยflags=0
close
คุณสามารถย้ายพวกเขาไปรอบ ๆ พร้อมกับdup
และเพื่อน ๆ หากคุณต้องการสับเปลี่ยนตัวอธิบายไฟล์ คุณสามารถตั้งธงบางคนที่มีfcntl
และใช้บัฟเฟอร์ stdio fdopen
หลังจากเรียก รายการดำเนินต่อไป ที่สำคัญมากคุณสามารถโทรselect
หรือpoll
เปิดไฟล์ประเภทใดก็ได้รวมถึงซ็อกเก็ตดังนั้นฟังก์ชั่นเหล่านี้จึงอนุญาตให้โปรแกรมปิดกั้นจนกว่าจะได้รับอินพุตผ่านวิธีการใด ๆ เพียงแค่แสดงรายการตัวอธิบายไฟล์
มีสายระบบพิเศษสำหรับบางชนิดซ็อกเก็ต (มีrecv
และsend
, shutdown
ฯลฯ ) เช่นมีสายเรียกระบบพิเศษสำหรับอุปกรณ์ ( ioctl
)
ไม่ใช่ทุกไฟล์ที่มีชื่อและไฟล์เหล่านั้นไม่มีอยู่ในโครงสร้างไดเรกทอรีเสมอไป ไพพ์ที่สร้างโดยpipe
(เช่นในเชลล์ไลน์) และซ็อกเก็ตที่สร้างโดยsocketpair
ไม่มีชื่อ แต่ยังคงเป็นไฟล์ ซ็อกเก็ตที่สร้างโดยsocket
มีชื่อซึ่งมีไวยากรณ์ขึ้นอยู่กับโดเมน ชื่อนี้ถูกส่งผ่านstruct sockaddr
ไปยังbind
และฟังก์ชั่นอื่น ๆ สำหรับAF_UNIX
ซ็อกเก็ตUnix ( ) ชื่อคือ a struct sockaddr_un
ซึ่งเป็นตระกูลและสตริง ขึ้นอยู่กับสตริงนี้สามารถเป็นชื่อไฟล์ (ซ็อกเก็ตที่มีชื่อสามารถสร้างขึ้นได้mknod
ในหลายรุ่นยูนิกซ์) หรือไม่ (เนมสเปซที่เป็นนามธรรม) สำหรับAF_INET
ซ็อกเก็ตIPv4 ( ) ชื่อคือ a struct sockaddr_in
ที่มีหมายเลขพอร์ตและที่อยู่ IP รวมทั้งprotocol
จากการsocket
โทร
ถ้าคุณstat
เป็นซ็อกเก็ตคุณจะเห็นว่ามันมีหมายเลขไอโหนดและคุณสมบัติอื่น ๆ ของไฟล์ปกติดังนั้นฉันจะจัดเป็นไฟล์ในระบบไฟล์ ตัวอย่าง:
# file live
live: socket
# stat live
File: `live'
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: fc03h/64515d Inode: 198817 Links: 1
Access: (0660/srw-rw----) Uid: (23129/ icinga) Gid: (23130/icinga-cmd)
Access: 2014-11-07 09:27:59.000000000 -0800
Modify: 2014-11-05 09:27:03.000000000 -0800
Change: 2014-11-05 09:27:03.000000000 -0800
11/17 ข้อมูลเพิ่มเติมสำหรับ Linux (ext3): ซ็อกเก็ตมีไอโหนด (ซึ่งเป็นบล็อกขนาด 256 ไบต์บนดิสก์) แต่ไม่มีบล็อกข้อมูลใด ๆ (คุณสามารถตรวจสอบได้โดยแยกไอโหนดและตรวจสอบพอยน์บล็อคข้อมูลหรือโดย ใช้ debugfs 'stat' ซึ่งแสดง Blockcount เป็น 0) ดังนั้นมันจึงมีเมทาดาทาไฟล์ (เจ้าของกลุ่มสิทธิ์ ฯลฯ ) แต่ไม่มีเนื้อหาข้อมูลบนดิสก์ สิ่งนี้เหมือนกับไฟล์เปล่าทั่วไป ( touch /tmp/foo
) ซึ่งมีจำนวนบล็อกเป็น 0 ในกรณีแรกฟิลด์ "type" ใน inode แสดง "socket"; ในกรณีที่สองมันแสดง "ไฟล์ปกติ"
การอ้างอิง: โครงสร้าง inode ext2 ; stat
,, dumpe2fs
และdebugfs
คำสั่ง
file
หรือstat
ทำให้มันเป็นไฟล์