linux管道與通訊端的調試工具

來源:互聯網
上載者:User
1)管道的調試/proc/pid/fd目錄下列出進程的管道和管道的索引號.我們用下面的程式來看管道在/proc/pid/fd目錄下的表現,如下:#include<unistd.h>#include<sys/types.h>#include<stdio.h>#include<stdlib.h>#include<string.h>int main(){        pid_t pid;        int fd[2],nbytes;        char string[]="data from child process";        char buf[100];        if(pipe(fd)<0)        {                perror("pipe");                exit(1);        }        if((pid=fork())==-1)        {                perror("fork");                exit(1);        }        if(pid==0)        {                close(fd[0]);                printf("childpid =%2d\n",getpid());                write(fd[1],string,sizeof(string));                close(fd[1]);                exit(0);        }        else        {                printf("parentpid =%2d\n",getpid());                sleep(30);                close(fd[1]);                nbytes=read(fd[0],buf,sizeof(buf));                printf("Received string:%s\n",buf);                close(fd[0]);        }        return 0;}編譯:gcc pipe.c -o pipe 運行:./pipe childpid =27695parentpid = 27694程式會在父進程執行時調用sleep(30),此時子進程已經完成對管道的寫入,並關閉了子進程的管道(讀/寫兩端).父進程在sleep(30)秒後,從管道讀取資訊並輸出.我們在父進程睡眠的時候,根據它的parentpid輸出,來查看它的檔案描述符,如下:ls -l /proc/27694/fdtotal 0lrwx------ 1 root root 64 Mar 18 13:06 0 -> /dev/pts/0lrwx------ 1 root root 64 Mar 18 13:06 1 -> /dev/pts/0lrwx------ 1 root root 64 Mar 18 13:06 2 -> /dev/pts/0lr-x------ 1 root root 64 Mar 18 13:06 3 -> pipe:[42753]l-wx------ 1 root root 64 Mar 18 13:06 4 -> pipe:[42753]這裡的3 -> pipe:[42753],表示管道的讀取端,4 -> pipe:[42753]表示管道的寫入端.相同我們也可以根據管道的索引號得到它的進程,如下:lsof |head -1 && lsof | grep 43046COMMAND     PID      USER   FD      TYPE     DEVICE     SIZE       NODE NAMEpipe      27780      root    3r     FIFO        0,6               43046 pipepipe      27780      root    4w     FIFO        0,6               43046 pipe2)通訊端的調試調試通訊端時兩個最有用的工具是netstat和lsof#include <stdio.h>#include <string.h>#include <signal.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define ASSERTNOERR(x, msg) do{\        if ((x) == -1){perror(msg); exit(1);}}while(0)#define SOCKNAME "localsock"int main (int argc, char *argv[]){        int s = socket(PF_LOCAL, SOCK_STREAM, 0);        struct sockaddr_un sa = {                .sun_family = AF_LOCAL,                .sun_path = SOCKNAME        };        int r = bind(s, (struct sockaddr *) &sa, sizeof(sa));        ASSERTNOERR(r, "bind");        r = listen(s, 0);        ASSERTNOERR(r, "listen");        struct sockaddr_un asa;        size_t addrlen = sizeof(asa);        int fd = accept(s, (struct sockaddr *) &asa, &addrlen);        ASSERTNOERR(fd, "accept");        while(1){                char buf[32];                fd_set fds;                FD_ZERO(&fds);                FD_SET(fd, &fds);                int r = select (fd+1, &fds, NULL, NULL, NULL);                ASSERTNOERR(r, "select");                int n = read(fd, buf, sizeof(buf));                printf("server read %d bytes\n", n);                if(n == 0)                        break;        }        unlink(SOCKNAME);        return 0;}編譯:gcc unix-socket.c -o unix-socket用netstat來查看處於監聽狀態的UNIX socket通訊端,如下:netstat -nlxpActive UNIX domain sockets (only servers)Proto RefCnt Flags       Type       State         I-Node PID/Program name    Pathunix  2      [ ACC ]     STREAM     LISTENING     4899   1967/sdpd           /var/run/sdpunix  2      [ ACC ]     STREAM     LISTENING     5534   2260/xfs            /tmp/.font-unix/fs7100unix  2      [ ACC ]     STREAM     LISTENING     6586   2468/1              /tmp/ssh-yWORhw2468/agent.2468unix  2      [ ACC ]     STREAM     LISTENING     8331   2879/unix-socket    /tmp/localsockunix  2      [ ACC ]     STREAM     LISTENING     4988   2030/pcscd          /var/run/pcscd.communix  2      [ ACC ]     STREAM     LISTENING     5151   2103/acpid          /var/run/acpid.socketunix  2      [ ACC ]     STREAM     LISTENING     5412   2206/gpm            /dev/gpmctlunix  2      [ ACC ]     STREAM     LISTENING     5631   2311/avahi-daemon:  /var/run/avahi-daemon/socketunix  2      [ ACC ]     STREAM     LISTENING     5257   2141/cupsd          /var/run/cups/cups.sockunix  2      [ ACC ]     STREAM     LISTENING     5677   2328/hald           @/var/run/hald/dbus-gzDLkbe0vzunix  2      [ ACC ]     STREAM     LISTENING     5678   2328/hald           @/var/run/hald/dbus-y2AFY83XQFunix  2      [ ACC ]     STREAM     LISTENING     4424   1755/python         /var/run/audit_eventsunix  2      [ ACC ]     STREAM     LISTENING     4810   1941/dbus-daemon    /var/run/dbus/system_bus_socket我們看到unix-socket程式產生的socket檔案,如下:unix  2      [ ACC ]     STREAM     LISTENING     8331   2879/unix-socket    /tmp/localsockACC:表示這個unix socket程式調用ACCEPT函數,處於接收的狀態.SOCK_STREAM:表示這個unix socket是可靠的基於串連的資料轉送,基本協議保證了按照傳輸的順序讀取資訊.I-NODE:表示通訊端的索引號,就像一個檔案.通過查看/proc/net/unix,也可以看到unix通訊端的資訊.cat /proc/net/unixNum       RefCount Protocol Flags    Type St Inode Pathd3341040: 00000002 00000000 00010000 0001 01  4899 /var/run/sdpd2893c80: 00000002 00000000 00010000 0001 01  5534 /tmp/.font-unix/fs7100d32dac80: 00000002 00000000 00010000 0001 01  6586 /tmp/ssh-yWORhw2468/agent.2468d32da3c0: 00000002 00000000 00010000 0001 01  8331 /tmp/localsockdb380c80: 00000002 00000000 00010000 0001 01  4988 /var/run/pcscd.commdb380900: 00000002 00000000 00010000 0001 01  5151 /var/run/acpid.socketdb380040: 00000002 00000000 00010000 0001 01  5412 /dev/gpmctld2893200: 00000002 00000000 00010000 0001 01  5631 /var/run/avahi-daemon/socketdb380580: 00000002 00000000 00010000 0001 01  5257 /var/run/cups/cups.sockdfcf4900: 00000012 00000000 00000000 0002 01  4416 /dev/logdfcf4e40: 00000002 00000000 00000000 0002 01  1081 @/org/kernel/udev/udevdd1029580: 00000002 00000000 00000000 0002 01  5686 @/org/freedesktop/hal/udev_eventd1029c80: 00000002 00000000 00010000 0001 01  5677 @/var/run/hald/dbus-gzDLkbe0vzd1029ac0: 00000002 00000000 00010000 0001 01  5678 @/var/run/hald/dbus-y2AFY83XQFdfcf4580: 00000002 00000000 00010000 0001 01  4424 /var/run/audit_eventsd3341c80: 00000002 00000000 00010000 0001 01  4810 /var/run/dbus/system_bus_socket可以通過lsof來查看unix通訊端資訊,如下:netstat -xnpl|grep localsockunix  2      [ ACC ]     STREAM     LISTENING     8331   2879/unix-socket    /tmp/localsocklsof /tmp/localsock              COMMAND    PID USER   FD   TYPE     DEVICE SIZE NODE NAMEunix-sock 2879 root    3u  unix 0xd32da3c0      8331 /tmp/localsock在這裡我們可以看使用者ID,檔案描述符.可以通過查看/proc/8331/fd/,來看檔案描述的資訊,如下:ls -l /proc/2879/fdtotal 0lrwx------ 1 root root 64 Mar 19 01:32 0 -> /dev/pts/0lrwx------ 1 root root 64 Mar 19 01:32 1 -> /dev/pts/0lrwx------ 1 root root 64 Mar 19 01:32 2 -> /dev/pts/0lrwx------ 1 root root 64 Mar 19 01:32 3 -> socket:[8331]對於tcp/udp的SOCKET通訊端,如下:查看tcp的SOCKET通訊端:netstat -tanpActive Internet connections (servers and established)Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   tcp        0      0 127.0.0.1:2208              0.0.0.0:*                   LISTEN      2119/hpiod          tcp        0      0 0.0.0.0:779                 0.0.0.0:*                   LISTEN      1869/rpc.statd      tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1830/portmap        tcp        0      0 0.0.0.0:23                  0.0.0.0:*                   LISTEN      2177/xinetd         tcp        0      0 127.0.0.1:631               0.0.0.0:*                   LISTEN      2141/cupsd          tcp        0      0 127.0.0.1:2207              0.0.0.0:*                   LISTEN      2124/python         tcp        0      0 :::22                       :::*                        LISTEN      2160/sshd           tcp        0      0 ::1:631                     :::*                        LISTEN      2141/cupsd          tcp        0    148 ::ffff:192.168.27.130:22    ::ffff:192.168.27.1:2892    ESTABLISHED 2468/2 查看udp的SOCKET通訊端:netstat -uanpActive Internet connections (servers and established)Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   udp        0      0 0.0.0.0:32768               0.0.0.0:*                               2311/avahi-daemon:  udp        0      0 0.0.0.0:773                 0.0.0.0:*                               1869/rpc.statd      udp        0      0 0.0.0.0:776                 0.0.0.0:*                               1869/rpc.statd      udp        0      0 0.0.0.0:68                  0.0.0.0:*                               1548/dhclient       udp        0      0 0.0.0.0:5353                0.0.0.0:*                               2311/avahi-daemon:  udp        0      0 0.0.0.0:111                 0.0.0.0:*                               1830/portmap        udp        0      0 0.0.0.0:631                 0.0.0.0:*                               2141/cupsd          udp        0      0 :::32769                    :::*                                    2311/avahi-daemon:  udp        0      0 :::5353                     :::*                                    2311/avahi-daemon:  通過lsof來查看tcp的資訊.lsof -n -i tcpCOMMAND    PID USER   FD   TYPE DEVICE SIZE NODE NAMEportmap   1830  rpc    4u  IPv4   4533       TCP *:sunrpc (LISTEN)rpc.statd 1869 root    7u  IPv4   4615       TCP *:779 (LISTEN)hpiod     2119 root    0u  IPv4   5185       TCP 127.0.0.1:2208 (LISTEN)python    2124 root    4u  IPv4   5201       TCP 127.0.0.1:2207 (LISTEN)cupsd     2141 root    3u  IPv6   5255       TCP [::1]:ipp (LISTEN)cupsd     2141 root    4u  IPv4   5256       TCP 127.0.0.1:ipp (LISTEN)sshd      2160 root    3u  IPv6   5303       TCP *:ssh (LISTEN)xinetd    2177 root    5u  IPv4   5416       TCP *:telnet (LISTEN)sshd      2468 root    3u  IPv6   6547       TCP 192.168.27.130:ssh->192.168.27.1:snifferdata (ESTABLISHED)通過lsof來查看udp的資訊.lsof -n -i udpCOMMAND    PID  USER   FD   TYPE DEVICE SIZE NODE NAMEdhclient  1548  root    4u  IPv4   4027       UDP *:bootpc portmap   1830   rpc    3u  IPv4   4532       UDP *:sunrpc rpc.statd 1869  root    3u  IPv4   4612       UDP *:wpages rpc.statd 1869  root    6u  IPv4   4602       UDP *:notify cupsd     2141  root    6u  IPv4   5259       UDP *:ipp avahi-dae 2311 avahi   13u  IPv4   5635       UDP *:mdns avahi-dae 2311 avahi   14u  IPv6   5636       UDP *:mdns avahi-dae 2311 avahi   15u  IPv4   5637       UDP *:filenet-tms avahi-dae 2311 avahi   16u  IPv6   5638       UDP *:filenet-rpc 在lsof的輸出可以看到檔案描述符及裝置的資訊,另外還有使用者資訊.最後我們來看一下管道和通訊端的INODE,每個檔案都有自己的INODE,但由於VFS(虛擬檔案系統)使所有的檔案系統都通用,使tmpfs/procfs下的檔案像駐留在磁碟上的檔案一樣.INODE儲存著檔案的資料結構,檔案系統中每個對象有一個唯一的INODE.INODE對於沒有檔案名稱的對象,包括socket和管道是非常有用的.TCP/UDP通訊端的INODE,可以用下面的命令來查看:lsof -i tcp -a -p 2468COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAMEsshd    2468 root    3u  IPv6   6547       TCP 192.168.27.130:ssh->192.168.27.1:snifferdata (ESTABLISHED)其它的DEIVCE就是它的INODE,NODE一欄只顯示TCP下面是UDP通訊端的例子:lsof -i udp -a -p 1869COMMAND    PID USER   FD   TYPE DEVICE SIZE NODE NAMErpc.statd 1869 root    3u  IPv4   4612       UDP *:wpages rpc.statd 1869 root    6u  IPv4   4602       UDP *:notify 對於UNIX的本地通訊端,可以直接用netstat來查看,如下:netstat -xnpActive UNIX domain sockets (w/o servers)Proto RefCnt Flags       Type       State         I-Node PID/Program name    Pathunix  17     [ ]         DGRAM                    4416   1774/syslogd        /dev/logunix  2      [ ]         DGRAM                    1081   385/udevd           @/org/kernel/udev/udevdunix  2      [ ]         DGRAM                    5686   2328/hald           @/org/freedesktop/hal/udev_event而對於管道,可以在/proc/pid/fd和lsof -p pid的方式來查看INODE
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.