Linux netcat listener (nc -l) หยุดทำงาน


0

บน Terminal Raspberry Pi 3 ของฉัน (Linux) ฉันพิมพ์ต่อไปนี้และกดEnter:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/' | nc -l 2345

Raspberry Pi 3 เป็นส่วนหนึ่งของเครือข่ายในบ้านของฉันที่มีที่อยู่คงที่ 192.168.0.8 จากนั้นใน mac ของฉันฉันพิมพ์ต่อไปนี้ในเบราว์เซอร์ของฉัน (Chrome) และกดEnter:

192.168.0.8:2345

ฉันเห็นคำขอ GET ของเบราว์เซอร์บน Linux Terminal ของฉัน (Raspberry Pi) แต่ncผู้ฟังติดและไม่ส่งคำตอบ (HTTP 302 เปลี่ยนเส้นทางข้อความ) ไปยังเบราว์เซอร์

เมื่อฉันหยุดncโปรแกรมโดยกดปุ่มCtrl+ Cเบราว์เซอร์จะได้รับข้อความตอบกลับและแสดงhttps://www.eff.orgเว็บไซต์

มีใครคิดncบ้างไหมว่าทำไมผู้ฟังถึงติดแทนที่จะส่งคำตอบและปิดการเชื่อมต่อ?


(1) คุณจะรู้ได้อย่างไรว่าncกระบวนการนั้น“ ติดอยู่”? คุณทำstraceหรือดมเครือข่ายหรือไม่? (2) แต่ก่อนอื่น\r\nให้ลองเพิ่มอันอื่นลงในส่วนท้ายของprintfสตริงข้อความ
G-Man

คำตอบ:


0

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

(หมายเหตุ: ในระหว่างการทดสอบของฉันฉันต้องการขั้นตอนสุดท้าย\r\nในการตอบกลับncเพื่อเปลี่ยนเส้นทางเบราว์เซอร์ของฉันให้สำเร็จดังนั้นตัวอย่างทั้งหมดของฉันใช้โปรแกรมแก้ไขนี้)


แก้ไข: แก้ไขง่าย ๆ

ที่นี่ฉันได้พบต่อไปนี้:

คำร้องขอ HTTP และการตอบกลับ HTTP ใช้รูปแบบข้อความทั่วไปของ RFC 822 สำหรับการถ่ายโอนข้อมูลที่ต้องการ รูปแบบข้อความทั่วไปนี้ประกอบด้วยสี่รายการต่อไปนี้

  • [ ... ]
  • [ ... ]
  • บรรทัดว่าง (เช่นบรรทัดที่ไม่มีอะไรนำหน้า CRLF) ที่ระบุถึงจุดสิ้นสุดของฟิลด์ส่วนหัว
  • [ ... ]

ดังนั้นคำตอบของคุณควรเป็น:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n\r\n' | ...

หลังจากได้รับสิ่งนี้แล้วเบราว์เซอร์ของคุณควรดำเนินการเปลี่ยนเส้นทางต่อไปยกเลิกการเชื่อมต่อไปยังncในนามของตนเอง ในช่วงต้นเดือนธันวาคม 2017 ทำงานได้กับ Opera และ Vivaldi มันไม่ทำงานกับ Firefox, Chrome หรือ Safari ซึ่งคุณอาจต้องการการแก้ไขอื่น (ดูด้านล่าง)



คำตอบดั้งเดิมตอนนี้ด้อยกว่า (อาจเป็นประโยชน์สำหรับการสื่อสารที่ไม่ใช่ HTTP ด้วยnc)

ตามคำตอบนี้บนเซิร์ฟเวอร์ผิดพลาดคุณจำเป็นต้องใช้-c, -qหรือตัวเลือกที่คล้ายกันขึ้นอยู่กับncการดำเนินงาน

ใน Debian ของฉันฉันมี-qรุ่นที่สามารถติดตั้งได้ แล้วก็

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -q 0 -l -p 2345

ทำงานได้ดี (หมายเหตุฉันต้อง-pระบุพอร์ตด้วย) คำอธิบายคือ:

-q seconds
หลังจากที่EOFเมื่อวันที่stdinรอการระบุจำนวนวินาทีแล้วเลิก หากวินาทีเป็นลบให้รอตลอดไป (ค่าเริ่มต้น)


หากncไม่มีตัวเลือกที่เหมาะสมการแก้ไขปัญหาอาจเป็นการตรวจจับการสื่อสารจากไคลเอนต์และฆ่าบรรทัดคำสั่งทั้งหมด ตัวอย่างที่ทำงานใน Debian ของฉันbash:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -l -p 2345 | { read foo; sleep 1; kill 0; }

เมื่อเรียกใช้ไพพ์bashวางทุกกระบวนการในกลุ่มกระบวนการเดียว kill 0ส่งสัญญาณไปยังกลุ่มกระบวนการทั้งหมด วิธีนี้ncถูกฆ่าตายประมาณ 1 วินาทีหลังจากการร้องขอใด ๆ readที่ได้รับการเรียกว่า


ขอบคุณ! ฉันลองแก้ไขอย่างง่ายโดยการเพิ่ม \ r \ n \ r \ n ที่ส่วนท้ายของสตริงตามที่คุณแนะนำ ใช้งานได้กับเบราว์เซอร์ Opera เท่านั้น (เวอร์ชั่นล่าสุด) อย่างไรก็ตามด้วย Firefox, Chrome หรือ Safari (เวอร์ชั่นล่าสุด) กระบวนการยังคงติดอยู่ แต่เมื่อฉันเพิ่ม-q 0ตัวเลือกในncคำสั่งมันทำงานได้ในทุกเบราว์เซอร์
โทมัส Grusz

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