如何通过Socket获取Asterisk服务器状态 - Python
我正在尝试通过Python的socket来获取Asterisk服务器的状态,但什么都没有发生。
这是我的代码:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.1.105'
PORT = 5038
s.connect((HOST, PORT))
params = """Action: login
Events: off
Username: admin
Secret: mypass
Action: status
Action: Logoff
"""
s.send(params)
data = s.recv(1024)
print data + '\n'
s.close()
我只收到一条消息,显示Asterisk的版本,其他的什么都没有。
希望有人能帮我解决这个问题。
提前谢谢大家。
2 个回答
1
处理这样简单的基于TCP的协议可能会变得有些棘手。
在这种情况下可能会遇到的问题:
- 每一行的结束符应该是'\r\n'(而不仅仅是'\n',就像你发送的那样)
- 你需要接收所有的输出,否则连接可能会被阻塞。请注意,输出可能会分成多个部分发送(虽然在这种情况下可能不会发生),你需要处理这些情况。
可以尝试这样做:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '192.168.1.105'
PORT = 5038
s.connect((HOST, PORT))
params = ["Action: login",
"Events: off",
"Username: admin",
"Secret: mypass"]
s.send("\r\n".join(params) + "\r\n")
# receive login response
data = ""
while "\r\n" not in data:
data += s.recv(1024)
s.send("Action: status\r\n\r\n")
# receive action response
data = ""
while "\r\n" not in data:
data += s.recv(1024)
print repr(data)
s.send("Action: Logoff\r\n\r\n")
s.close()
2
你的代码写得有点问题。Asterisk AMI(一个通信协议)要求命令之间要用\r\n来结束。
你需要把每个命令放在一个单独的数据包里:
params = """Action: login
Events: off
Username: admin
Secret: mypass"""
s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'
params = 'Action: status'
s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'
params = 'Action: Logoff'
s.send(params + '\r\n')
data = s.recv(1024)
print data + '\n'
这样就可以解决问题了。当然,你可能还想为这个写个函数或者其他的东西,但这样做就能让它正常工作。
记得把AMI命令分开哦!