Có thể để lộ đường hầm TCP trong Linux dưới dạng thiết bị ký tự đặc biệt không?


10

Gần đây tôi đã tìm thấy trong tài liệu QNX rằng nó cho phép thiết lập IPC dựa trên thông báo giữa các quy trình trên các máy vật lý riêng biệt bằng cách sử dụng thiết bị nối tiếp ( dev/serX) và nó làm tôi tự hỏi:

Linux có thể tạo ra thiết bị đặc biệt toàn hệ thống cho đường hầm TCP / UDP không? Một cái gì đó như ncstdin / stdout tiếp xúc công khai dưới / dev / cái gì đó.

Cuối cùng, tôi muốn có thể viết một cái gì đó vào tập tin đó trên một máy và nhận nó ở đầu bên kia chẳng hạn:

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

#machine2:
cat < /dev/somedev

Tôi đã xem xét nccon người nhưng tôi không tìm thấy bất kỳ tùy chọn nào để chỉ định nguồn / đích io ngoài stdio.


Xem Tại sao các giao diện mạng không ở / dev như các thiết bị khác? trong đó bao gồm các phần tại sao không phải là một phần.
Gilles 'SO- ngừng trở nên xấu xa'

1
Đề cập đáng trân trọng: Các thiết bị tun / tap có thể được tạo trong / dev, nhưng bạn phải tự đóng gói IP trên chúng. Vô cùng hữu ích cho một số mục đích.
pjc50

Câu trả lời:


19

socat có thể làm điều này và nhiều thứ khác với những thứ giống như "dòng"

Một cái gì đó sử dụng ý tưởng cơ bản này sẽ làm điều đó cho bạn:

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

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

(phỏng theo Trang ví dụ )

Nếu bạn muốn mã hóa, bạn có thể sử dụng một biến thể của ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkmáy1 và một cái gì đó giống như ssl:server-host:1443,cert=client.pem,cafile=server.crttrên máy2

(Thêm về ssl xã hội )


7

Truyền tin cần được thực hiện ở lớp cao hơn; TCP không có khái niệm về một thông điệp - các kết nối TCP truyền các luồng của octet.

Bạn có thể đạt được một cái gì đó giống như những gì bạn yêu cầu ncđặt tên ống , xem man mkfifo; hoặc kiểm tra socatnhư Alex Stragies chỉ ra.

Nếu không có dịch vụ lớp giữa, các vấn đề cơ bản là (1) dữ liệu không thể được ghi vào mạng trừ khi có ai đó ở đầu bên kia lắng nghe và (2) các kết nối TCP là hai chiều.

Vì bạn không thể ghi dữ liệu vào mạng trừ khi có ai đó lắng nghe, bạn phải luôn khởi động người nghe trước khi bạn có thể gửi dữ liệu. (Trong một hệ thống chuyển tin nhắn, quá trình xử lý các tin nhắn sẽ cung cấp một số loại bộ đệm.)

Ví dụ của bạn có thể dễ dàng viết lại:

  • Đầu tiên bắt đầu một trình nghe trên machine2 (đích):

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

    Trong ví dụ của bạn, điều này sẽ là

     nc -l 1234 | cat
    

    Điều này sẽ chặn và chờ ai đó gửi một số dữ liệu tới cổng 1234.

  • Sau đó, bạn có thể gửi một số dữ liệu từ machine1 (nguồn):

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

    Trong ví dụ của bạn, điều này sẽ là

     echo "Hello" | nc machine2 1234
    

Nếu bạn muốn xử lý dữ liệu nhận được theo một cách nào đó và phản hồi, bạn có thể sử dụng phương tiện đồng xử lý của trình bao. Ví dụ: đây là một máy chủ web rất đơn giản (và rất cứng đầu):

#! /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

Xem cách đạt được giao tiếp hai chiều giữa phần chính của tập lệnh và bộ đồng xử lý bằng cách sử dụng các bộ mô tả tệp trong mảng $ncfd.


Bạn đã đúng, và tôi đã thừa nhận điều đó trong câu trả lời. Không thể có một thiết bị nhân vật mà không có một số loại phần mềm trung gian.
AlexP

Hình như bạn có một UUOC ở đó.
Michael Hampton

1
@MichaelHampton: Đó là ví dụ được cung cấp bởi OP. Tôi cho rằng đó catlà viết tắt của "một số quá trình đọc cho stdin".
AlexP

5

Nếu bạn chỉ muốn kết nối hai máy tính bằng một chương trình cơ bản như nc, bạn có thể chuyển hướng từ / đến /dev/tcp/<host>/<port>.

Đây không phải là thiết bị thực tế mà là một tiểu thuyết được tạo ra bởi bash, vì vậy những thứ như cat /dev/tcp/foo/19sẽ không hoạt động, nhưng cat < /dev/tcp/foo/19sẽ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.