日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Go語(yǔ)言實(shí)現(xiàn)UDP協(xié)議及TCP通訊_Golang

作者:奮斗的大橙子 ? 更新時(shí)間: 2022-09-16 編程語(yǔ)言

?、使用Golang創(chuàng)建?一個(gè)TCP連接

1.服務(wù)端處理理流程

  • a.監(jiān)聽(tīng)端口
  • b.接受客戶(hù)端的鏈接
  • c.創(chuàng)建Goroutine,處理這個(gè)鏈接(?個(gè)服務(wù)端要鏈接多個(gè)客戶(hù)端,所以使用Goroutine?常簡(jiǎn)單)

題外話(huà):要是用Java、C#服務(wù)這邊每?個(gè)請(qǐng)求都開(kāi)?個(gè)線(xiàn)程處理的話(huà),頂多?千個(gè),但是Goroutine就?常簡(jiǎn)單。

package main
 
import (
    "fmt"
    "net"
)
 
func main() {
    //1.建立監(jiān)聽(tīng)端口
    listen, err := net.Listen("tcp", "0.0.0.0:20000")
    if err != nil {
        fmt.Println("listen failed, err:", err)
        return
    }
 
    fmt.Println("listen Start...:")
 
    for {
        //2.接收客戶(hù)端的鏈接
        conn, err := listen.Accept()
        if err != nil {
            fmt.Printf("accept failed, err:%v\n", err)
            continue
        }
        //3.開(kāi)啟一個(gè)Goroutine,處理鏈接
        go process(conn)
    }
}
 
//處理請(qǐng)求,類(lèi)型就是net.Conn
func process(conn net.Conn) {
 
    //處理結(jié)束后關(guān)閉鏈接
    defer conn.Close()
    for {
        var buf [128]byte
        n, err := conn.Read(buf[:])
        if err != nil {
            fmt.Printf("read from conn failed, err:%v", err)
            break
        }
        fmt.Printf("recv from client, content:%v\n", string(buf[:n]))
    }
 
}

2.客戶(hù)端處理流程

  • a.和服務(wù)端建立一個(gè)鏈接
  • b.進(jìn)行數(shù)據(jù)的收發(fā)
  • c.關(guān)閉鏈接
package main
 
import (
    "bufio"
    "fmt"
    "net"
    "os"
    "strings"
)
 
func main() {
    //1.建立一個(gè)鏈接(Dial撥號(hào))
    conn, err := net.Dial("tcp", "0.0.0.0:20000")
    if err != nil {
        fmt.Printf("dial failed, err:%v\n", err)
        return
    }
 
    fmt.Println("Conn Established...:")
 
    //讀入輸入的信息
    reader := bufio.NewReader(os.Stdin)
    for {
        data, err := reader.ReadString('\n')
        if err != nil {
            fmt.Printf("read from console failed, err:%v\n", err)
            break
        }
 
        data = strings.TrimSpace(data)
        //傳輸數(shù)據(jù)到服務(wù)端
        _, err = conn.Write([]byte(data))
        if err != nil {
            fmt.Printf("write failed, err:%v\n", err)
            break
        }
    }
}

執(zhí)??下:

客戶(hù)端:

服務(wù)端:

?、使用Golang創(chuàng)建?個(gè)HTTP連接

  • A.HTTP協(xié)議是基于TCP協(xié)議之上的?本協(xié)議。
  • B.每行?本使?\r\n結(jié)尾,當(dāng)連續(xù)兩個(gè)\r\n時(shí),表示整個(gè)數(shù)據(jù)包結(jié)束。
package main
 
import (
    "fmt"
    "io"
    "net"
)
 
func main() {
    conn, err := net.Dial("tcp", "www.baidu.com:80")
    if err != nil {
        fmt.Printf("dial failed, err:%v\n", err)
        return
    }
 
    data := "GET / HTTP/1.1\r\n"
    data += "HOST: www.baidu.com\r\n"
    data += "connection: close\r\n"
    data += "\r\n\r\n"
 
    //寫(xiě)入數(shù)據(jù)
    _, err = io.WriteString(conn, data)
    if err != nil {
        fmt.Printf("wirte string failed, err:%v\n", err)
        return
    }
 
    var buf [1024]byte
    for {
        //讀取返回的數(shù)據(jù)
        n, err := conn.Read(buf[:])
        if err != nil || n == 0 {
            break
        }
 
        fmt.Println(string(buf[:n]))
    }
}

三、使?用Golang創(chuàng)建?個(gè)UDP連接

1.服務(wù)流程,相比于TCP連接需要Accept一個(gè)鏈接,UDP不需要進(jìn)?這步操作,服務(wù)端代碼如下:

package main
 
import (
    "fmt"
    "net"
)
 
func main() {
    //建立一個(gè)UDP的監(jiān)聽(tīng),這里使用的是ListenUDP,并且地址是一個(gè)結(jié)構(gòu)體
    listen, err := net.ListenUDP("udp", &net.UDPAddr{
        IP:   net.IPv4(0, 0, 0, 0),
        Port: 8080,
    })
    if err != nil {
        fmt.Printf("listen failed, err:%v\n", err)
        return
    }
 
    for {
        var data [1024]byte
        //讀取UDP數(shù)據(jù)
        count, addr, err := listen.ReadFromUDP(data[:])
        if err != nil {
            fmt.Printf("read udp failed, err:%v\n", err)
            continue
        }
 
        fmt.Printf("data:%s addr:%v count:%d\n", string(data[0:count]), addr, count)
        //返回?cái)?shù)據(jù)
        _, err = listen.WriteToUDP([]byte("hello client"), addr)
        if err != nil {
            fmt.Printf("write udp failed, err:%v\n", err)
            continue
        }
    }
}

2.客戶(hù)端流程

package main
 
import (
    "fmt"
    "net"
)
 
func main() {
    // 創(chuàng)建連接
    socket, err := net.DialUDP("udp4", nil, &net.UDPAddr{
        IP:   net.IPv4(127, 0, 0, 1),
        Port: 8080,
    })
    if err != nil {
        fmt.Println("連接失敗!", err)
        return
    }
    defer socket.Close()
    // 發(fā)送數(shù)據(jù)
    senddata := []byte("hello server!")
    _, err = socket.Write(senddata)
    if err != nil {
        fmt.Println("發(fā)送數(shù)據(jù)失敗!", err)
        return
    }
    // 接收數(shù)據(jù)
    data := make([]byte, 4096)
    read, remoteAddr, err := socket.ReadFromUDP(data)
    if err != nil {
        fmt.Println("讀取數(shù)據(jù)失敗!", err)
        return
    }
    fmt.Println(read, remoteAddr)
    fmt.Printf("%s\n", data)
}

原文鏈接:https://www.cnblogs.com/dcz2015/p/11235186.html

欄目分類(lèi)
最近更新