GNU/Linux >> Znalost Linux >  >> Linux

Jak určit dobu připojení soketu v systému Linux

Můžete zkusit následující:

  1. získejte PID (řekněme $pid ) programu přidáním -p možnost na netstat .

  2. identifikujte správný řádek v /proc/net/tcp v souboru local_address a/nebo rem_address pole (všimněte si, že jsou v hexadecimálním formátu, konkrétně IP adresa je vyjádřena v pořadí bajtů little-endian), také se ujistěte, že st je 01 (pro ESTABLISHED );

  3. poznamenejte si související inode pole (řekněme $inode );

  4. vyhledejte toto inode mezi deskriptory souborů v /proc/$pid/fd a nakonec dotaz na čas přístupu k souboru symbolického odkazu:

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

To je hrozná práce... zde je skript (útržek), který zautomatizuje výše uvedené body, vyžaduje vzdálenou adresu a vytiskne čas provozu zásuvky v sekundách:

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")
}

(Upravit díky Alexovi za opravy)

Příklad:

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

Tyto otázky mi pomohly, ale zjistil jsem, že používám lsof místo netstat dovolte mi vyhnout se všem HEX věcem:

Pro proces ${APP} spustit uživatelem ${USER} , následující vrátí všechny otevřené sokety na IP adresu ${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

lsof obsahuje PID také, ale nejsem si jistý, jak jej získat a číslo zařízení.

Toto bylo testováno na Amazon Linux.


Skript od cYrus mi fungoval, ale musel jsem to trochu opravit (abych se zbavil "L" v hexadecimální adrese a aby port byl 4místný hex):

--- 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. Jak se Linux dostal k sálovému počítači

  2. Jak používat Linux Touch Command + příklady

  3. Linux – Jak změřit čas, kdy dorazí paket?

  1. Jak zjistit velikost vyrovnávací paměti soketu linuxu

  2. Jak linuxové jádro určuje pořadí volání __init?

  3. Jak mohu odeslat zprávu na můj socket.io websocket z příkazového řádku v linuxu?

  1. Jak používat Linuxový příkaz grep

  2. Jak zjistit, kdy byl soubor Spfile vytvořen na serveru Linux

  3. Jak zjistím velikost bloku oddílu ext3 v systému Linux?