<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] > [參考](https://blog.csdn.net/qq_31967569/article/details/82704340) ## 實例 <details> <summary>client.go </summary> ``` package main import ( "fmt" "log" "net" "os" "strconv" "strings" "time" ) const HAND_SHAKE_MSG = "我是打洞消息" var ( tag string ) func main() { // 當前進程標記字符串,便于顯示 tag = os.Args[1] port,_:= strconv.Atoi(tag) srcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: port} // 注意端口必須固定 dstAddr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 9981}// 實際中 127.0.0.1 改為 公網,即可打洞 conn, err := net.DialUDP("udp", srcAddr, dstAddr) if err != nil { fmt.Println(err) } if _, err = conn.Write([]byte("hello, I'm new peer:" + tag)); err != nil { log.Panic(err) } data := make([]byte, 1024) n, remoteAddr, err := conn.ReadFromUDP(data) if err != nil { fmt.Printf("error during read: %s", err) } conn.Close() anotherPeer := parseAddr(string(data[:n])) fmt.Printf("local:%s server:%s another:%s\n", srcAddr, remoteAddr, anotherPeer.String()) // 開始打洞 bidirectionHole(srcAddr, &anotherPeer) } func parseAddr(addr string) net.UDPAddr { t := strings.Split(addr, ":") port, _ := strconv.Atoi(t[1]) return net.UDPAddr{ IP: net.ParseIP(t[0]), Port: port, } } func bidirectionHole(srcAddr *net.UDPAddr, anotherAddr *net.UDPAddr) { conn, err := net.DialUDP("udp", srcAddr, anotherAddr) if err != nil { fmt.Println(err) } defer conn.Close() // 向另一個peer發送一條udp消息(對方peer的nat設備會丟棄該消息,非法來源),用意是在自身的nat設備打開一條可進入的通道,這樣對方peer就可以發過來udp消息 if _, err = conn.Write([]byte(HAND_SHAKE_MSG)); err != nil { log.Println("send handshake:", err) } go func() { for { time.Sleep(10 * time.Second) if _, err = conn.Write([]byte("from [" + tag + "]")); err != nil { log.Println("send msg fail", err) } } }() for { data := make([]byte, 1024) n, _, err := conn.ReadFromUDP(data) if err != nil { log.Printf("error during read: %s\n", err) } else { log.Printf("收到數據:%s\n", data[:n]) } } } ``` </details> <br/> <details> <summary>peer_server.go</summary> ``` package main import ( "fmt" "log" "net" "time" ) func main() { listener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 9981}) if err != nil { fmt.Println(err) return } log.Printf("本地地址: <%s> \n", listener.LocalAddr().String()) peers := make([]net.UDPAddr, 0, 2) data := make([]byte, 1024) for { n, remoteAddr, err := listener.ReadFromUDP(data) if err != nil { fmt.Printf("error during read: %s", err) } log.Printf("<%s> %s\n", remoteAddr.String(), data[:n]) peers = append(peers, *remoteAddr) // 等待兩個udp 建立連接就互相轉發數據 if len(peers) == 2 { log.Printf("進行UDP打洞,建立 %s <--> %s 的連接\n", peers[0].String(), peers[1].String()) listener.WriteToUDP([]byte(peers[1].String()), &peers[0]) listener.WriteToUDP([]byte(peers[0].String()), &peers[1]) time.Sleep(time.Second * 8) log.Println("中轉服務器退出,仍不影響peers間通信") return } } } ``` </details> <br/> 分別執行 ``` go run peer.go go run client.go 1998 go run client.go 1999 ``` 原理: peer作為打洞服務等待client 進行連接,第一個client 連接后繼續等待,直到存在兩個連接后客戶端可以嘗試直接連接對等方.等雙方直連后,就可以關閉打洞服務了
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看