GNU/Linux >> Linux Esercitazione >  >> Linux

Come determinare il tempo di connessione del socket su Linux

Puoi provare quanto segue:

  1. ottieni il PID (ad esempio $pid ) del programma aggiungendo il -p opzione a netstat .

  2. identificare la riga corretta nel /proc/net/tcp guardando il file local_address e/o rem_address campi (nota che sono in formato esadecimale, in particolare l'indirizzo IP è espresso in ordine di byte little-endian), assicurati anche che il st è 01 (per ESTABLISHED );

  3. nota il inode associato campo (ad esempio $inode );

  4. cerca quel inode tra i descrittori di file in /proc/$pid/fd e infine interrogare il tempo di accesso al file del collegamento simbolico:

    find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
    

È un duro lavoro... ecco uno script (stub) per automatizzare i punti precedenti, richiede l'indirizzo remoto e stampa il tempo di attività del socket in secondi:

function suptime() {
    local addr=${1:?Specify the remote IPv4 address}
    local port=${2:?Specify the remote port number}
    # convert the provided address to hex format
    local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('<L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")
    local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")
    # get the PID of the owner process
    local pid=$(netstat -ntp 2>/dev/null | awk '$6 == "ESTABLISHED" && $5 == "'$addr:$port'"{sub("/.*", "", $7); print $7}')
    [ -z "$pid" ] && { echo 'Address does not match' 2>&1; return 1; }
    # get the inode of the socket
    local inode=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
    [ -z "$inode" ] && { echo 'Cannot lookup the socket' 2>&1; return 1; }
    # query the inode status change time
    local timestamp=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %[email protected])
    [ -z "$timestamp" ] && { echo 'Cannot fetch the timestamp' 2>&1; return 1; }
    # compute the time difference
    LANG=C printf '%s (%.2fs ago)\n' "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
}

(Modifica, grazie ad Alex per le correzioni)

Esempio:

$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)

Questa domanda mi è stata utile, ma ho trovato l'uso di lsof invece di netstat fammi evitare tutte le cose HEX:

Per un processo ${APP} eseguito dall'utente ${USER} , quanto segue restituisce tutti i socket aperti all'indirizzo IP ${IP}:

PEEID=$(sudo pgrep -u ${USER} ${APP}) && for i in `sudo lsof -anP -i -u logstash | grep ${IP} | awk '{print $6}'` ; do echo "${device} time" ; sudo find /proc/${PEEID}/fd -lname "socket:\[${device}\]" -printf %t 2> /dev/null  ; echo  ;  done

Il lsof contiene il PID anche, ma non sono sicuro di come ottenerlo e il numero del dispositivo.

Questo è stato testato su Amazon Linux.


Lo script di cYrus ha funzionato per me, ma ho dovuto correggerlo un po' (per eliminare una "L" nell'indirizzo esadecimale e rendere la porta un esadecimale a 4 cifre):

--- suptime.orig    2015-08-20 15:46:12.896652464 +0200
+++ suptime 2015-08-20 15:47:48.560074728 +0200
@@ -7,8 +7,8 @@
     hex_addr=$(python -c "
 import socket, struct;
 print hex(struct.unpack('<L',
-socket.inet_aton('$addr'))[0])[2:].upper().zfill(8)")
-    hex_port=$(python -c "print hex($port)[2:].upper()")
+socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8)")
+    hex_port=$(python -c "print hex($port)[2:].upper().zfill(4)")
     inode=$(awk '$3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
     time=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %[email protected])
     LANG=C printf '%.2fs' $(bc <<<"$(date +%s.%N) - $time")

Linux
  1. Come trovare quando lo Spfile è stato creato su un server Linux

  2. Come convertire i caratteri esadecimali in ASCII nella shell di Linux?

  3. Come ottenere l'ora di inizio di un processo Linux di lunga durata?

  4. Come trovare la dimensione del buffer del socket di Linux

  5. In che modo il kernel Linux determina l'ordine delle chiamate __init?

Come impostare o modificare il fuso orario in Linux

Controlla il fuso orario in Linux

Comprendere il comando dell'ora in Linux

Come determinare cosa sta utilizzando più spazio su disco su un server Linux?

Come rimuovo una connessione socket CLOSE_WAIT

Come posso determinare la dimensione del blocco di una partizione ext3 su Linux?