怎么停止一个后台的Server程序

写了一个Socket Server 程序,该程序在监听client端的socket request的请求的同时可以接受command行的输入,可以接受一些Command 输入并相应, 如果命令行输入QUIT, 这个Socket server程序会退出。 

学校要求写一个自动测试程序,这样问题变得有些复杂, 需要在后台启动这个server程序,并接受pipe来的in文件, 在处理玩pipe来的in文件处理后, 等待一段时间接受client端的链接请求, 最后接受QUIT指令结束程序。 

总结下来就是时序如下:

假设程序为 a.out , 输入文件为 a.in

Step1 : a.out < a.in  

Step2:  wait some times for client socket input

Step3: input "QUIT" to a.out 让 a.out退出

最开始的做法是使用Bash

a.out < a.in &
PID=$!
sleep(5)
kill -9 $PID

因为step1之后a.out的输入被pipe接管了,没有办法再输入'QUIT‘, 就使用kill -9强杀了。由于使用的是socket, 有时候会导致socket没有正常结束,下一次启动的时候会出现bind错误。

研究了一段时间后,发现用python的subprocess可以解决这个问题,让程序优雅的退出。

import subprocess
import time
import sys

def main(btide_param, input_filename, output_filename):
    command = ["btide", btide_param]

    # Reading input data from file
    with open(input_filename, "r") as file:
        btide_in = file.read()

    # Determine how to handle output based on whether an output file was provided
    if output_filename is None:
        process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        stdout_destination = None
    else:
        output_fd = open(output_filename, "w")
        process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=output_fd, stderr=subprocess.PIPE, text=True)
        stdout_destination = output_fd
    
    # Sending initial input
    process.stdin.write(btide_in)
    process.stdin.flush()

    # Introducing a delay
    time.sleep(1)

    # Sending subsequent commands
    process.stdin.write('\nQUIT\n')
    process.stdin.flush()

    # Closing stdin to indicate no more input will be sent
    # process.stdin.close()

    # Handling output and waiting for process to finish
    if stdout_destination is None:
        # Reading output directly if no file is used
        output, errors = process.communicate()
        if errors:
            print("Errors:", errors)
        print(output)
    else:
        # Waiting for the process to complete if output is redirected to a file
        process.stdin.close()
        process.wait()
        stdout_destination.close()

if __name__ == "__main__":
    btide_args = sys.argv[1] if len(sys.argv) > 1 else ""
    file_in = sys.argv[2] if len(sys.argv) > 2 else ""
    file_out = sys.argv[3] if len(sys.argv) > 3 else None

    print(f"args={btide_args}, in={file_in}, out={file_out}")
    main(btide_args, file_in, file_out)

这里碰到的坑是如果结果需要输出到文件中, 再process.wait()前需要调用process.stdin.close(). 如果是直接输出到屏幕上, 要调用process.communicate()去等待程序结束。至于为什么还没有搞明白。总之,可以工作了。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值