AutoIt:如何处理应用程序端口被占用的情况

为公司的部署工程师书写了一个autoIt应用程序,现在遇到下面的一种情况:

产品分服务器端和客户端,启动的时候,会启用1785端口,然后彼此通信;

现在我的autoIt应用程序需要做的事情是:

如果1785端口被占用,该怎么办? 如果部署工程师熟悉配置文件,把端口1785更换成别的端口怎么办?

解决方案如下:

1. 产品开发组应该配置自己的端口为不常用端口,定义一个小的范围,于是可以通过AutoIt,判断目前配置的端口是否在1700-1710之间,只要在这个之间,就来判断该端口是否打开,如果打开了,就可以考虑关闭使用该端口的应用程序;如果不在 1700-1710之间,就给出提示信息:端口信息配置有误,让实施人员联系开发人员重新配置。

2. 调用dos命令,netstat -ano|findstr ":1701" 可以判断1701端口是否被占用。

如果返回的是空字符串,表明端口没有被占用,不影响配置文件的继续执行;

如果返回的端口不为空,就需要做以下几件事:

1) 获取使用1701端口的所有应用程序PID

;Get the PIDs which take the $port
Func get_PIDs($port)
    $tcp_str = _GetDOSOutput('netstat -aon|findstr ":' & $port &'"')
    ;ConsoleWrite($tcp_str & @CRLF)
    $tcp_array = StringSplit($tcp_str, @CR)
    $len = UBound($tcp_array)
    Local $pids[$len-1]
    For $i = 1 To $len-1
        $splits = StringSplit($tcp_array[$i], " ")
        $pid =_ArrayPop($splits)
        _ArrayPush($pids, $pid)
    Next
    Return _ArrayUnique($pids)
EndFunc

2. 关闭使用了1701端口的应用程序

;Close the process by the known port
Func close_process_by_port($port)
    $pids = get_PIDs($port)
    For $i = 1 To UBound($pids) -1
        If $pids[$i] <> 0 And $pids[$i] <> "" Then
            close_process(Number($pids[$i]))
        EndIf
    Next
EndFunc

3. 关于close_process 函数(以前该函数使用了判断语句:ProcessExists,如果存在就删除,不存在就不删除,但是这样会导致某些问题:程序被意外关闭了,此时内存中该程序还是存在的,可是ProcessExists 却判断不存在,就什么工作都不做了)

; Close some process
Func close_process($process_name)
    ;We will close $process_name no matter it exists or not.
    ProcessClose($process_name)
    ProcessWaitClose($process_name)
EndFunc

4. 关于_GetDOSOutput 函数,该函数是从别人那儿获取的,难点在参数 $STDERR_CHILD 以及 $STDOUT_CHILD,为了获取的结果准确,$sCommand尽量细节一些,确保该函数能获取想要的结果。

; Return the dos command output to a string
Func _GetDOSOutput($sCommand)
    Local $iPID, $sOutput = ""
    $iPID = Run('"' & @ComSpec & '" /c ' & $sCommand, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    While 1
        $sOutput &= StdoutRead($iPID, False, False)
        If @error Then
            ExitLoop
        EndIf
    Sleep(10)
    WEnd
    Return $sOutput
EndFunc

5. 以上的准备工作完成之后,就可以完成主函数里面的内容了。

$port = get_tcp_port($sync_file)
_GUICtrlListBox_AddString($hListBox, "Check port: " & $port & " whether it is in use or not")
If $port > 1699 And $port < 1710 Then
   close_process_by_port($port)
Else
   _GUICtrlListBox_AddString($hListBox, "端口: " & $port & " 不正确,请正确配置 sync.xml 文件节点 TCP:LocalHostPort")
EndIf

该思路可以解决目前的问题,也许有人会觉得:凭啥关掉别人的程序?就因为端口占用了?难道不能新生成一个端口?

在测试自己的应用程序的时候,我尝试设置一些奇怪的端口,比喻1, 135,然后运行close_process_by_port,我发现系统会崩溃;

于是我设置关闭应用程序,也只有在端口在1700-1710之间,最大程度避免风险;

目前该应用程序会运行在局域网里面两台可以连接的机器上,如果我随机生成没有被占用的端口,就没法保证服务器,客户端端口的一致性。目前我还没有好的思路搞同步。

原文地址:https://www.cnblogs.com/autotest/p/3512452.html