当前位置 博文首页 > Golang 端口复用测试的实现

    Golang 端口复用测试的实现

    作者:翔云123456 时间:2021-04-29 17:43

    先给出结论:

    同一个进程,使用一个端口,然后连接关闭,大约需要30s后才可再次使用这个端口。

    测试

    首先使用端口9001连接服务端,发送数据,然后关闭连接,接着再次使用端口9001连接服务端,如果连接失败,间隔15s后,再次尝试,最多尝试3次,。

    client

    package main
    import (
    
     "bufio"
     "fmt"
     "net"
     "os"
     "time"
    )
    
    func DialCustom(network, address string, timeout time.Duration, localIP []byte, localPort int)(net.Conn,error) {
     netAddr := &net.TCPAddr{Port:localPort}
    
     if len(localIP) != 0 {
     netAddr.IP = localIP
     }
    
     fmt.Println("netAddr:", netAddr)
    
     d := net.Dialer{Timeout: timeout, LocalAddr: netAddr}
     return d.Dial(network, address)
    }
    
    
    func getOneConn() {
    
     serverAddr := "127.0.0.1:8080"
    
     // 172.28.172.180
     //localIP := []byte{0xAC, 0x1C, 0xAC, 0xB4} // IP
     localIP := []byte{} // any IP
     localPort := 9001
    
     var conn net.Conn
     var err error
    
     for i:=0;i<3;i++{
    
     conn, err = DialCustom("tcp", serverAddr, time.Second*10, localIP,localPort)
     if err != nil {
     fmt.Println("dial failed:", err)
     if i == 2 {
     os.Exit(1)
     }
     time.Sleep(15*time.Second)
     } else {
     break
     }
     }
    
     defer conn.Close()
    
    
     buffer := make([]byte, 512)
     reader := bufio.NewReader(conn)
    
     n, err2 := reader.Read(buffer)
     if err2 != nil {
     fmt.Println("Read failed:", err2)
     return
     }
    
     fmt.Println("count:", n, "msg:", string(buffer))
    
    }
    
    
    func main() {
     getOneConn()
     fmt.Println("=========================")
     getOneConn()
     fmt.Println("=========================")
     select{}
    
    }
    

    server

    package main
    
    import (
     "fmt"
     "net"
     "log"
    )
    
    func main() {
    
     addr := "0.0.0.0:8080"
    
     tcpAddr, err := net.ResolveTCPAddr("tcp",addr)
    
     if err != nil {
     log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
     }
    
     listener, err := net.ListenTCP("tcp", tcpAddr)
     if err != nil {
     log.Fatalf("listen %s fail: %s", addr, err)
     } else {
     
     log.Println("rpc listening", addr)
     }
    
    
     for {
     conn, err := listener.Accept()
     if err != nil {
     log.Println("listener.Accept error:", err)
     continue
     }
     
     go handleConnection(conn)
     
     }
    
    }
    
    
    func handleConnection(conn net.Conn) {
    
     //defer conn.Close()
    
     var buffer []byte = []byte("You are welcome. I'm server.")
    
     n, err := conn.Write(buffer)
    
     if err != nil {
     
     fmt.Println("Write error:", err)
     }
     fmt.Println("send:", n)
    
     fmt.Println("connetion end")
    }

    output

    client输出:

    $ ./client
    netAddr: :9001
    count: 28 msg: You are welcome. I'm server.
    =========================
    netAddr: :9001
    dial failed: dial tcp :9001->127.0.0.1:8080: bind: address already in use


    netAddr: :9001
    dial failed: dial tcp :9001->127.0.0.1:8080: bind: address already in use

    netAddr: :9001
    count: 28 msg: You are welcome. I'm server.
    =========================

    经过3次重试,30s后,才可以重新使用同一个端口9001进行连接。也就是同一个进程的情况狂下,一个连接关闭后,端口大约30s后才可以被使用。

    js
    下一篇:没有了