Python网络编程:实现心跳机制

百度百科上对于心跳机制的描述:心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。

应用:当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编码的。

你可能感兴趣的:(Python网络编程:实现心跳机制)