เป็นไปได้หรือไม่ที่จะเปิดเผยช่องสัญญาณ TCP ใน Linux เป็นอุปกรณ์ตัวอักษรพิเศษ?


10

เมื่อเร็ว ๆ นี้ฉันพบในเอกสารประกอบ QNX ที่อนุญาตให้ติดตั้ง IPC แบบข้อความระหว่างกระบวนการในเครื่องทางกายภาพแยกโดยใช้อุปกรณ์อนุกรม ( dev/serX) และทำให้ฉันสงสัยว่า:

เป็นไปได้ใน Linux ที่จะสร้างอุปกรณ์พิเศษทั้งระบบสำหรับอุโมงค์ TCP / UDP? สิ่งที่ต้องการncstdin / stdout เปิดเผยต่อสาธารณะภายใต้ / dev / บางสิ่งบางอย่าง

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

#machine1:
echo "Hello" > /dev/somedev

#machine2:
cat < /dev/somedev

ฉันดูncผู้ชาย แต่ฉันไม่พบตัวเลือกใด ๆ ในการระบุแหล่งที่มา / ปลายทางของ io นอกเหนือจาก stdio



1
รางวัลชมเชย: อุปกรณ์ tun / tap สามารถสร้างขึ้นได้ใน / dev แต่คุณต้องทำการ encapsulation IP ด้วยตัวคุณเอง มีประโยชน์อย่างยิ่งสำหรับวัตถุประสงค์บางอย่าง
pjc50

คำตอบ:


19

socat สามารถทำสิ่งนี้และอื่น ๆ อีกมากมายกับสิ่งที่คล้ายกับ "ลำธาร"

สิ่งที่ใช้แนวคิดพื้นฐานนี้ควรทำเพื่อคุณ:

Machine1$ socat tcp-l:54321,reuseaddr,fork pty,link=/tmp/netchardev,waitslave

Machine2$ socat pty,link=/tmp/netchardev,waitslave tcp:machine1:54321

(ดัดแปลงจากหน้าตัวอย่าง )

หากคุณต้องการเข้ารหัสคุณสามารถใช้รูปแบบของssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkบน machine1 และสิ่งที่คล้ายssl:server-host:1443,cert=client.pem,cafile=server.crtกับบน machine2

(เพิ่มเติมเกี่ยวกับsocat ssl )


7

การส่งผ่านข้อความต้องดำเนินการในระดับที่สูงขึ้น TCP ไม่มีความคิดของข้อความ - การเชื่อมต่อ TCP ถ่ายโอนสตรีมของ octets

คุณสามารถทำสิ่งที่คล้ายกับสิ่งที่คุณร้องขอด้วยncและชื่อไปป์ให้ดูman mkfifo; หรือตรวจสอบsocatตามที่ Alex Stragies ระบุ

หากไม่มีบริการเลเยอร์กลางปัญหาพื้นฐานคือ (1) ข้อมูลไม่สามารถเขียนไปยังเครือข่ายได้เว้นแต่จะมีใครบางคนที่อีกฝ่ายรับฟังและ (2) การเชื่อมต่อ TCP นั้นเป็นแบบสองทิศทาง

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

ตัวอย่างของคุณสามารถเขียนใหม่ได้ง่าย:

  • ก่อนอื่นให้เริ่มฟังจาก machine2 (ปลายทาง):

     nc -l 1234 | ...some processing with the received data...
    

    ในตัวอย่างของคุณนี่จะเป็น

     nc -l 1234 | cat
    

    การดำเนินการนี้จะบล็อกและรอให้บางคนส่งข้อมูลบางอย่างไปยังพอร์ต 1234

  • จากนั้นคุณสามารถส่งข้อมูลบางอย่างจาก machine1 (แหล่งที่มา):

    ...make up some data... | nc machine2 1234
    

    ในตัวอย่างของคุณนี่จะเป็น

     echo "Hello" | nc machine2 1234
    

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

#! /bin/bash

while :; do
  coproc ncfd { nc -l 1234; }
  while :; do
    read line <&${ncfd[0]} || break
    line="$(
      echo "$line" |
      LC_ALL=C tr -cd ' -~'
    )"
    echo >&2 "Received: \"$line\""
    if [ "$line" = "" ]; then
      echo >&${ncfd[1]} "HTTP/1.0 200 OK"
      echo >&${ncfd[1]} "Content-Type: text/html"
      echo >&${ncfd[1]} "Connection: close"
      echo >&${ncfd[1]} ""
      echo >&${ncfd[1]} "<title>It works!</title>"
      echo >&${ncfd[1]} "<center><b>It works!</b></center>"
      echo >&${ncfd[1]} "<center>-- $(date +%Y-%m-%d\ %H:%M:%S) --</center>"
      break
    fi
  done
  kill %%
  sleep 0.1
done

มาดูกันว่าการสื่อสารแบบสองทิศทางระหว่างเนื้อหาหลักของสคริปต์และตัวประมวลผลร่วมโดยใช้ file descriptors ในอาร์เรย์$ncfdได้อย่างไร


คุณพูดถูกและฉันยอมรับว่าในคำตอบ ไม่สามารถมีอุปกรณ์ตัวอักษรได้หากไม่มีซอฟต์แวร์สื่อกลาง
AlexP

ดูเหมือนว่าคุณมี UUOC อยู่ที่นั่น
Michael Hampton

1
@MichaelHampton: นั่นเป็นตัวอย่างที่ได้รับจาก OP ฉันคิดว่านั่นcatหมายถึง "กระบวนการอ่านสำหรับ stdin"
AlexP

5

หากคุณเพียงแค่ต้องการที่จะเชื่อมต่อคอมพิวเตอร์สองเครื่องใช้โปรแกรมพื้นฐานเช่น NC /dev/tcp/<host>/<port>คุณสามารถเปลี่ยนเส้นทางจาก

สิ่งเหล่านี้ไม่ใช่อุปกรณ์จริง แต่เป็นนิยายที่สร้างโดย bash ดังนั้นสิ่งต่าง ๆ เช่นcat /dev/tcp/foo/19จะไม่ทำงาน แต่cat < /dev/tcp/foo/19จะทำ

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