ใช้เข้า / ออกชื่อไปป์สำหรับการเชื่อมต่อ TCP


15

ฉันเล่นซอให้เรื่องนี้ทำงานได้ซักพักแล้วดังนั้นฉันจึงสงสัยว่าความเข้าใจผิดพื้นฐานบางอย่างเกี่ยวกับการทำงานของท่อเป็นสาเหตุของปัญหาของฉัน

เป้าหมายของฉันคือการเริ่มต้นการเชื่อมต่อ TCP ไปยังรีโมตโฮสต์ผ่านnetcatและมีไพพ์ที่มีชื่อสองไฟล์ในระบบไฟล์: กระบวนการหนึ่งที่กระบวนการสามารถอ่านเพื่อรับข้อมูลขาเข้าและอื่น ๆ ที่กระบวนการสามารถเขียนไปยังข้อมูลขาออก ฉันกำลังใช้สิ่งก่อสร้างต่อไปนี้:

mkfifo in
mkfifo out
cat out | netcat foo.bar.org 4000 > in &

จากที่นี่ฉันต้องการอนุญาตให้กระบวนการอื่นอ่านและเขียนไปยัง / จากการเชื่อมต่อ TCP แบบเปิดนี้ ควร "ใช้งานได้" หรือมีเหตุผลว่าทำไมการสร้างเช่นนี้ไม่สามารถใช้งานได้?

สิ่งที่ดูเหมือนจะเกิดขึ้นในปัจจุบันคือฉันสามารถอ่านได้outโดยไม่มีปัญหา แต่เมื่อฉันเขียนถึงinฉันรับเอาท์พุทพูดถึงท่อที่ขาดและการสื่อสารที่ตามมาทั้งหมดดูเหมือนจะตาย คิด?

(ที่เกี่ยวข้อง: ฉันใช้มา แต่เดิม:

netcat foo.bar.org 4000 < out > in &

แต่พบว่ามันบล็อกการรอการป้อนข้อมูล ฉันอยากรู้เกี่ยวกับสิ่งนี้เช่นกัน แต่มันอาจจะดีกว่าในคำถามที่แยกต่างหาก)

คำตอบ:


6
cat out | netcat foo.bar.org 4000 > in &

ฉันคิดว่าปัญหาคือว่าcatจะออกทันทีที่ได้รับEOFจากoutไปป์ และเมื่อcatออกจากท่อที่เหลือ (รวมถึงnetcat) ก็จะถูกยกเลิกเช่นกัน

ลองทำสิ่งนี้แทน:

while true; do cat out; done | netcat foo.bar.org 4000 > in &

ดังนั้นcatได้รับการเริ่มต้นใหม่ได้บ่อยเท่าที่จำเป็นและมีการจัดการใด ๆEOFที่ปรากฏในoutท่อได้อย่างมีประสิทธิภาพ


ฉันลองสิ่งนี้ แต่ยังคงได้รับwrite(stdout): Broken pipeหลังจาก (หรือหลังจากนั้นไม่นาน) เขียนลงในoutไปป์
noffle

2

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

mkfifo loopFF
netcat -t -l -p 4000 <loopFF | tee loopFF

ตอนนี้ในเทอร์มินัลอื่นตั้งค่าการเชื่อมต่อ Fifo ของคุณไปยังเซิร์ฟเวอร์ของคุณ:

mkfifo in
mkfifo out
netcat 127.0.0.1 4000 <out >in &

พิมพ์เซิร์ฟเวอร์ใดก็ตามที่ส่งถึงคุณ (และให้มันทำงานต่อไปหากคุณใช้inFifo ในแอปพลิเคชันที่ปิดปลายด้านหนึ่งเมื่อมีการยกเลิกnetcatปิดการเชื่อมต่อ)

cat in &

และในอาคารผู้โดยสารเดียวกัน:

cat > out

ตอนนี้สิ่งที่คุณพิมพ์จะถูกพิมพ์อีกครั้ง (หลังจากกดปุ่ม Enter) การปิดคำสั่งนี้จะเป็นการปิดการเชื่อมต่อ


ฉันเห็นว่าไม่ใช่กรณีเมื่อฉันลองด้วยตัวเอง แต่ทำไมnetcat -t -l -p 4000 < loopFF | tee loopFFไม่ทำให้ลูปป้อนกลับแบบไม่มีที่สิ้นสุดกับตัวเอง
noffle

@noffle เพราะอย่างที่ฉันพูดnetcatจะปิดทุกครั้งที่การเชื่อมต่อเครือข่ายปิด หากคุณปิดไคลเอนต์ (ซึ่งส่งสตริงและรับสตริงเดียวกัน) netcatเซิร์ฟเวอร์จะถูกปิดเช่นกัน ฉันเขียนรหัสเซิร์ฟเวอร์สำหรับตัวเองในกรณีนี้ที่บังคับตัวเองให้จัดการกับลูกค้าหลายรายและเชื่อมต่อกับลูกค้าอีกครั้ง
saeedn

2

การวิเคราะห์ของสตีเว่นจันทร์ดูดีกับฉัน: catผลตอบแทนหลังจากเขียน 1 ของคุณไปoutเพราะ FIFO emptyคือ เพื่อหลีกเลี่ยงปัญหานั้นคือการทำให้กระบวนการเปิดฟีฟ่าในโหมดเขียนหนึ่งcatในตัวอย่างร้อง:

mkfifo in
mkfifo out
cat > out &
echo $! > out-pid
cat out | netcat foo.bar.org 4000 > in &

(ไฟล์ out-pid เป็นวิธีหยุดทุกสิ่ง: kill -9 $(cat out-pid) .)

อีกตัวอย่างหนึ่งที่นี่

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