百度百科上对于心跳机制的描述:心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。
应用:当B服务器宕机时,A服务器需要知道B是否宕机,便可通过心跳机制实现.
服务端脚本:serv.py
#coding:utf8
import socket
import time
import os
import threading
import argparse
MAX_BYTES = 1024
is_alive = 0
def server(host,port,delay):
if not isinstance(host,str):
raise KeyError("The host must be a string like \'127.0.0.1\'")
if not isinstance(port,int):
raise KeyError('The port must be a integer')
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind((host,port))
def recv():
global is_alive
while True:
#print('test')
data,addr = sock.recvfrom(MAX_BYTES)
#print(data)
is_alive += 1
if is_alive >= 10000:
is_alive = 0
client = threading.Thread(target=recv)
client.setDaemon(True)
client.start()
IS_ALIVE = True
while IS_ALIVE:
before = is_alive
time.sleep(delay)
if before is is_alive:
result = os.popen('python test.py')
print(result)
IS_ALIVE = False
sock.close()
def main():
#server('0.0.0.0', 5000, 5)
parse = argparse.ArgumentParser(description='Listen to a port and excute a file')
parse.add_argument('-H',nargs='?',default='127.0.0.1',const='127.0.0.1')
parse.add_argument('-P',nargs='?',default=2333,const=2333,type=int)
parse.add_argument('-D',nargs='?',default=5,const=5)
result = parse.parse_args()
print(result.H,result.P,result.D)
server(result.H,result.P,result.D)
if __name__=='__main__':
main()
客服端脚本:clit.py
#coding:utf8
import argparse
import socket
import time
def client(host,port,delay):
udp_sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
try:
udp_sock.connect((host,port))
#udp_sock.sendto('2333',address=(host,port))
udp_sock.send('2333'.encode('ascii'))
except:
pass
finally:
time.sleep(delay)
def main():
parse = argparse.ArgumentParser(description="Sent a message to a host")
parse.add_argument('-H',nargs='?',default='127.0.0.1',const='127.0.0.1')
parse.add_argument('-P',nargs='?',default=2333,const=2333,type=int)
parse.add_argument('-D',nargs='?',default=1,const=1)
result = parse.parse_args()
print(result.H,result.P,result.D)
client(result.H,result.P,result.D)
if __name__=='__main__':
main()
-H用于指定监听的主机
-P用于指定监听的端口
-D用于指定超过多长时间未收到消息即认为客户端宕机
当远程客户端宕机时,服务端在规定时间内没有收到消息,将在命令行中执行os.popen()中的语句。
再说说本次踩的坑,由于一开始在客户端中没有对发送的消息进行编码,所以服务端死活都没有收到信息,但是翻了翻以前写的Python2版本的代码,却是能够收到的,后来想了想这其中的区别,是因为Python2默认编码便是ASCII码。Python3的默认编码为unicode,而底层传输是没法传输unicode编码的。