开心健康幸福 發表於 2019-9-3 16:02:00

Golang检测Linux服务器端口占用

<ul>
<li><strong>代码实现</strong></li>
</ul>
<pre><code class="language-Go">func CheckPort(port int) error {
    checkStatement := fmt.Sprintf(`netstat -anp | grep -q %d ; echo $?`, port)
    output, err := exec.Command("sh", "-c", checkStatement).CombinedOutput()
    if err != nil {
      return err
    }
    // log.Println(output, string(output)) ==&gt; 0 或 1
    result, err := strconv.Atoi(strings.TrimSuffix(string(output), "\n"))
    if err != nil {
      return err
    }
    if result == 0 {
      return fmt.Errorf("端口%d已被占用", port)
    }

    return nil
}
</code></pre>
<br>
- **纠错思路**
<ul>
<li>第8行原代码为:<code>result, err := strconv.Atoi(string(output))</code>,<br>
报错为: <code>strconv.Atoi: parsing "0\n": invalid syntax</code></li>
<li>经排查,<code>CombinedOutput()</code>函数的执行结果<code>0\n(1\n)</code>包含换行符<code>\n</code>,<br>
利用<code>strings.TrimSuffix()</code>函数删除换行符<code>\n</code><br>
<br><br></li>
<li><strong>延伸知识</strong>
<ul>
<li><code>strings.TrimSuffix()</code>和<code>strings.TrimRight()</code>的区别</li>
</ul>
</li>
</ul>
<pre><code class="language-Go">func main() {
        str1 := "abcdabceeebdc"
        str2 := "abcd"
        str3 := "abced"
        str4 := "ebdc"
    // `TrimRight(s, cutset string) string`指从`s`右端开始,删除所有`cutset`中出现的字符
    // 若从右到左的过程中遇到其他字符,则停止删除。
        fmt.Println(strings.TrimRight(str1, str2))   
        fmt.Println("空行:", strings.TrimRight(str1, str3))   

    // `TrimSuffix(s, suffix string)`删除后缀`suffix` ,若不匹配,返回s
        fmt.Println(strings.TrimSuffix(str1, str4))   
        fmt.Println(strings.TrimSuffix(str1, str2))   
}

// 输出结果:
// abcdabceee
// 空行:
// abcdabcee
// abcdabceeebdc
</code></pre>
<h3 id="2019-09-24改">2019-09-24改</h3>
<pre><code class="language-Go">func CheckPort(port int) error {
    checkStatement := fmt.Sprintf("netstat -anp | grep -q %d ", port)
    output, err := exec.Command("sh", "-c", checkStatement).CombinedOutput()
    if err != nil {
      return nil   // err != nil 说明端口没被占用
    }

    if len(output) &gt; 0 {
      return fmt.Errorf("端口%d已被占用", port)
    }

    return nil
}
</code></pre>
<blockquote>
<p><strong>注:以上方法的缺陷是目标操作系统上有可能没有netstat命令</strong></p>
</blockquote>
<h3 id="2019-09-29改">2019-09-29改</h3>
<pre><code class="language-Go">
func CheckPort(port string) error {
        var err error
       
        tcpAddress, err := net.ResolveTCPAddr("tcp4", ":" + port)
        if err != nil {
                return err
        }
       
        for i := 0; i &lt; 3; i++ {
                listener, err := net.ListenTCP("tcp", tcpAddress)
                if err != nil {
                        time.Sleep(time.Duration(100) * time.Millisecond)
                        if i == 3 {
                                return err
                        }
                        continue
                } else {
                        listener.Close()
                        break
                }
        }

        return nil
}
</code></pre><br><br>
来源:https://www.cnblogs.com/GaiHeiluKamei/p/11453623.html
頁: [1]
查看完整版本: Golang检测Linux服务器端口占用