GNU/Linux >> Belajar Linux >  >> Linux

Di Bash, Bisakah Saya Membuka Soket Secara Asinkron dan Menggunakannya Nanti?

Saya tidak tahu bahwa Bash mendukung begitu banyak fitur canggih! Saya mulai mengerjakan program jaringan sederhana untuk mencoba dan menggunakan beberapa hal yang saya temukan ini. Program khusus saya adalah klien redis dasar yang ditulis sepenuhnya dalam Bash. Saat ini, saya dapat melakukan sesuatu seperti berikut:

redis_command -c "ping" redis{001..100}:{6379..6400}

Ini akan mengirim perintah "ping" ke semua instance (sekitar 2100) dan mengembalikan hasilnya. Saat ini saya mengirim perintah "ping" secara serial, tetapi saya pikir saya dapat mempercepat program saya dengan melakukan semua pembuatan soket awal secara paralel. Saya menguji program saya dengan/tanpa pengoptimalan, dan menyadari bahwa pengoptimalan saya sebenarnya memperlambat segalanya. Begini tampilan pengoptimalannya:

declare -A SOCKETS
function get_socket {
  # args: <hostname> <port>
  # returns: the socket number, or failure return code

  # verify args
  if [[ -z "${1}" ]]; then
    return 1
  fi
  if [[ -z "${2}" ]]; then
    return 1
  fi

  local HOSTPORT="${1}:${2}"
  if [[ -z ${SOCKETS[${HOSTPORT}]} ]]; then
    exec {fd}<>/dev/tcp/${1}/${2}
    SOCKETS[${HOSTPORT}]=${fd}
    RES=${fd}
  else
    RES="${SOCKETS[${HOSTPORT}]}"
  fi
}

if [[ ${PRECONNECT} -eq 1 ]]; then
  echo -n "Pre-connecting to ${#HOSTS[@]} instances... " >&2
  for HOST in ${HOSTS[@]}; do
    get_socket "${HOST%%:*}" "${HOST##*:}" &
    PIDS+=($!)
  done

  # make sure all of our async connections finished before starting
  # TODO, check for errors
  for PID in ${PIDS[@]}; do
    wait ${PID}
  done
  echo "done" >&2
fi

Biasanya, fungsi get_socket() sendiri berfungsi dengan baik. Jika saya perlu mengirim perintah ke server tertentu, saya memanggil get_socket() sebelumnya, dan meneruskan FD ke fungsi lain yang benar-benar mengirim perintah dan mem-parsing respons. Dalam skenario pra-koneksi, saya memanggil get_socket di latar belakang melalui &. Karena get_socket()&berjalan dalam proses terpisah, FD yang dibuat tidak tersedia/dapat diakses dalam proses panggilan, jadi pengoptimalan saya tidak berguna.

Apakah ada cara untuk mengirim soket di bash, atau cara lain agar saya dapat memparalelkan koneksi saya tanpa menggunakan proses terpisah?

Jawaban yang Diterima:

Tidak dengan /dev/tcp/x/y secara langsung, tetapi Anda dapat menggunakan pipa untuk berkomunikasi dengan proses yang dimulai di latar belakang untuk menghubungkan soket TCP dan mentransfer data.

Sesuatu seperti

coproc hostA {
  exec {fd}<> /dev/tcp/127.0.0.1/80
  cat <&$fd & cat >&$fd
}

# same for hostB...

echo -e 'HEAD / HTTP/1.0rnr' >&${hostA[1]}
cat <&${hostA[0]}

Saat Anda akhirnya menjalankan dua cat tetap, Anda mungkin juga melakukannya tanpa /dev/tcp (yang tidak selalu diaktifkan) dan gunakan misalnya socat:

coproc hostA { socat - tcp:localhost:80; }

Atau, Anda dapat menghapus ketergantungan pada bash dengan menggunakan pipa bernama:

mkfifo hostA.in hostA.out
socat - tcp:localhost:80 < hostA.in > hostA.out &

Linux
  1. Cara Menyimpan Perintah Linux Dan Menggunakannya Sesuai Permintaan

  2. Kapan menggunakan Bash dan kapan menggunakan Perl/Python/Ruby?

  3. Bagaimana cara menggunakan perintah jam tangan dan pekerjaan bersama di Bash?

  1. Linux – Disimpan Di File /dev/pts Dan Bisakah Kita Membukanya?

  2. Bagaimana saya bisa menggunakan wildcard gaya ms-dos dengan ls dan mv?

  3. Tidak dapat menggunakan gubernur cpufreq userspace dan menyetel frekuensi cpu

  1. Cara Menggunakan Perintah Shutdown Linux, Restart Direncanakan dan segera

  2. Gunakan grep untuk menemukan konten dalam file dan memindahkannya jika cocok

  3. Bagaimana saya bisa menggunakan perintah alias dengan xargs?