พฤติกรรมของ Netcat / socat กับ piping และ UDP?


13

ฉันเดาว่ามันใกล้เคียง linux - Netcat หยุดฟังการรับส่งข้อมูล UDP - Super User แต่ฉันคิดว่าฉันควรจะถามอะไรเพิ่มเติม

เท่าที่ เวอร์ชันของ netcat ฉันใช้ Ubuntu 11.04 และเป็นค่าเริ่มต้น netcat บนซึ่งฉันเดาว่าเป็น openbsd หนึ่ง:

$ nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]

นี่คือสิ่งที่ฉันพบว่าแปลก: กรณีแรกทำงานได้อย่างที่คาดไว้ - ฉันเปิดเซิร์ฟเวอร์ UDP ในเทอร์มินัลเดียว:

$ sudo nc -ul 5000

... และในเทอร์มินัลอื่นฉันเริ่มต้นการเชื่อมต่อไคลเอนต์ UDP ใหม่ - และฉันพิมพ์ hello สามครั้งกด ENTER หลังจากแต่ละ:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

... และกลับไปที่เทอร์มินัลเซิร์ฟเวอร์ก็มีการพิมพ์ hello สามครั้งตามที่คาดไว้:

$ sudo nc -ul 5000 
hello
hello
hello
^C

จนถึงตอนนี้ทุกอย่างทำงานได้ตามที่คาดหวัง อย่างไรก็ตามสมมติว่าฉันลองตอนนี้เหมือนกันโดยการป้อนข้อมูลเข้าสู่ลูกค้า ดังนั้นสร้างเซิร์ฟเวอร์ UDP แรกในเทอร์มินัลเดียว:

$ sudo nc -ul 5000

... และอีกอันหนึ่งไพพ์ข้อมูลบางส่วนเข้าไป nc ในฐานะลูกค้า UDP:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C

... หลังจากคำสั่งไคลเอนต์เชลล์จะหยุดการทำงานเสมือนรออินพุต - ดังนั้นฉันจึงพิมพ์ hello และป้อนอีกสองครั้ง แต่เซิร์ฟเวอร์ได้ลงทะเบียนเพียงครั้งแรก hello (ซึ่งส่งผ่านทาง echo ) นอกจากนี้แม้ว่าคุณกด Ctrl-C และพยายามทำซ้ำไคลเอ็นต์ echo hello | nc -u 127.0.0.1 5000 คำสั่งเซิร์ฟเวอร์จะ ยังคง ยังคงมีการรายงานเพียงคนแรก hello:

$ sudo nc -ul 57130 
hello
^C

... และหลังจากหยุดเซิร์ฟเวอร์ด้วย Ctrl-C และรีสตาร์ทอีกครั้งหนึ่งสามารถทำซ้ำไคลเอ็นต์ echo hello | nc -u 127.0.0.1 5000 สั่งการและสังเกตการทำงาน

นี่คือวิธีที่ nc ควรจะทำตัวอย่างไร ฉันคาดว่าอย่างน้อยการโทรซ้ำเพื่อ echo hello | nc -u 127.0.0.1 5000 จะลงทะเบียนหรือไม่ - โดยไม่ต้องรีสตาร์ทเซิร์ฟเวอร์ หรืออาจมีสวิตช์บรรทัดคำสั่งพิเศษสำหรับลักษณะการทำงานนั้น

แก้ไข: ฉันพบการนำเสนอ PDF ที่ดีนี้: socat - การจัดการซ็อกเก็ตทุกชนิด ซึ่งมีดังต่อไปนี้ netcat VS socat บันทึก:

netcat - ข้อ จำกัด
●หนึ่งภาพเท่านั้น (สิ้นสุดหลังจากปิดซ็อกเก็ต)
...
ตัวอย่างที่ 1: การเปลี่ยน netcat
...
●ไคลเอนต์ UDP พร้อมพอร์ตต้นทาง:
nc -u -p 500 1.2.3.4 500
socat - udp: 1.2.3.4: 500, sp = 500
●เซิร์ฟเวอร์ TCP:
nc -l -p 8080
socat - tcp-l: 8080, นำมาใช้ใหม่
...

... อย่างไรก็ตามฉันค่อนข้างจะได้รับพฤติกรรมเหมือนข้างต้นถ้าฉันแทนที่คำสั่งเซิร์ฟเวอร์ด้วย " socat - udp4-listen:5000,reuseaddr "- และสายลูกค้าด้วย" socat - udp:127.0.0.1:5000 "... ด้วยอินพุต piped" echo hello | socat - udp:127.0.0.1:5000 "ความแตกต่างเพียงอย่างเดียวคือที่นี่คำสั่งอย่างน้อยก็มีอยู่หลังจากคำนั้น hello ถูกส่งไปแล้ว - อย่างไรก็ตามการรันคำสั่งต่อเนื่องอีกครั้งจะไม่ทำให้เกิดการรับสัญญาณใด ๆ ที่เซิร์ฟเวอร์จนกว่าเซิร์ฟเวอร์จะรีสตาร์ท

คำตอบ:


19

ตกลงฉันคิดว่าอย่างน้อยฉันก็มีบางอย่างด้วย socat - คือตัวเลือก fork จะต้องผนวกเข้ากับบรรทัดเซิร์ฟเวอร์:

$ socat - udp4-listen:5000,reuseaddr,fork

... และจากนั้นในสถานีอื่นเราสามารถโทรหา echo ท่อเข้า socat บรรทัดไคลเอ็นต์หลายครั้งบนบรรทัดรับคำสั่งเนื่องจากจะออกทันที ( ดีหลังจากครึ่งวินาที :) ):

$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000

... และกลับไปที่เทอร์มินัลแรกเราจะเห็นว่าเซิร์ฟเวอร์แสดงทั้งสามสำเร็จแล้ว hello s:

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C

โปรดทราบว่าแม้จะมี fork -ed socat เซิร์ฟเวอร์บรรทัด echo "hello" | nc -u 127.0.0.1 5000 จะยังคง 'ล็อก' ราวกับรอการป้อนข้อมูลจากผู้ใช้ อย่างไรก็ตามหลังจาก Ctrl-C และรันคำสั่งอีกครั้งนั่นคือ

$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C

... fork -ed socat เซิร์ฟเวอร์จะแสดงสามรายการ hello s โดยไม่จำเป็นต้องเริ่มต้นใหม่ ..

ดูเหมือนว่า openBSD นี้ netcat ไม่มี fork ตัวเลือก - แต่ฉันไม่แน่ใจว่ามันมีหนึ่งที่สอดคล้องกับมัน ..

อย่างไรก็ตามหวังว่านี่จะช่วยใครซักคน
ไชโย!


4

netcat ของคุณกำลังอ่านเอาต์พุตจาก stdout ของ echo เมื่อคุณใช้ไปป์เท่านั้นไม่ใช่ "เชื่อมต่อ" กับคีย์บอร์ดอีกต่อไป ในการรับการตอบสนองที่คุณคาดหวังคุณสามารถเพิ่ม "hello" สามตัวของคุณลงในไฟล์ได้

cat [myfile] | nc -u 127.0.0.1 5000

สวัสดี @OldWolf - ขอบคุณมากสำหรับคำตอบของคุณ! ฉันลองใช้คำแนะนำของคุณ (ในลักษณะที่ค่อนข้างซับซ้อนกว่า " cat $(echo -e "hello\nhello\nhello\n" > tmpf; echo tmpf) | nc -u 127.0.0.1 5000 ") อย่างไรก็ตามในขณะที่ฉันเห็นสาม hello s, ปริศนาอะไรที่ฉันยังคงมีอยู่: คำสั่งนั้นก็จะเรียงลำดับของ "ล็อค" เช่นถ้ารอการป้อนข้อมูลที่พิมพ์จากผู้ใช้และหลังจาก Ctrl-C และรันใหม่อีกครั้งเซิร์ฟเวอร์จะไม่เห็นข้อมูลใด ๆ จนกว่าจะรีสตาร์ท!? นั่นคือสิ่งที่ฉันอยากรู้มากกว่านี้ - ไชโย!
sdaau

2
nc กำลังรอ EOF อยู่ซึ่งในกรณีนี้จะไม่ได้รับจนกว่าคุณจะส่งสัญญาณออกไปยังโปรแกรม
OldWolf

อ่าฉันเข้าใจแล้ว - ขอบคุณมากสำหรับคำอธิบายนั้น @OldWolf! ดูเหมือนว่า socat สามารถหลีกเลี่ยงสิ่งนั้นได้ด้วย fork ตัวเลือก ... ขอบคุณอีกครั้งไชโย!
sdaau

2

หากคุณทำการฟัง nc มันจะแสดงว่า netcat กำลังรอการเชื่อมต่อและเมื่อได้รับแล้วจะเชื่อมต่อกับโฮสต์และพอร์ตนั้น คุณต้องเพิ่ม '-k' เพื่อดำเนินการต่อและ '-w 0' เพื่อหมดเวลาการเชื่อมต่อแต่ละครั้งหลังจาก 0 วินาที Socat เป็นตัวเลือกที่ดีกว่าฉันคิดว่า

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