Go语言实现UDP协议及TCP通讯

2022-07-25 10:56:44

⼀、使用Golang创建⼀一个TCP连接

1.服务端处理理流程

    a.监听端口b.接受客户端的链接c.创建Goroutine,处理这个链接(⼀个服务端要链接多个客户端,所以使用Goroutine⾮常简单)

    题外话:要是用Java、C#服务这边每⼀个请求都开⼀个线程处理的话,顶多⼏千个,但是Goroutine就⾮常简单。

    package main
     
    import (
        "fmt"
        "net"
    )
     
    func main() {
        //1.建立监听端口
        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.接收客户端的链接
            conn, err := listen.Accept()
            if err != nil {
                fmt.Printf("accept failed, err:%v\n", err)
                continue
            }
            //3.开启一个Goroutine,处理链接
            go process(conn)
        }
    }
     
    //处理请求,类型就是net.Conn
    func process(conn net.Conn) {
     
        //处理结束后关闭链接
        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.客户端处理流程

      a.和服务端建立一个链接b.进行数据的收发c.关闭链接
      package main
       
      import (
          "bufio"
          "fmt"
          "net"
          "os"
          "strings"
      )
       
      func main() {
          //1.建立一个链接(Dial拨号)
          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)
              //传输数据到服务端
              _, err = conn.Write([]byte(data))
              if err != nil {
                  fmt.Printf("write failed, err:%v\n", err)
                  break
              }
          }
      }

      执⾏⼀下:

      客户端:

      服务端:

      ⼆、使用Golang创建⼀个HTTP连接

        A.HTTP协议是基于TCP协议之上的⽂本协议。B.每行⽂本使⽤\r\n结尾,当连续两个\r\n时,表示整个数据包结束。
        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"
         
            //写入数据
            _, err = io.WriteString(conn, data)
            if err != nil {
                fmt.Printf("wirte string failed, err:%v\n", err)
                return
            }
         
            var buf [1024]byte
            for {
                //读取返回的数据
                n, err := conn.Read(buf[:])
                if err != nil || n == 0 {
                    break
                }
         
                fmt.Println(string(buf[:n]))
            }
        }

        三、使⽤用Golang创建⼀个UDP连接

        1.服务流程,相比于TCP连接需要Accept一个链接,UDP不需要进⾏这步操作,服务端代码如下:

        package main
         
        import (
            "fmt"
            "net"
        )
         
        func main() {
            //建立一个UDP的监听,这里使用的是ListenUDP,并且地址是一个结构体
            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数据
                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)
                //返回数据
                _, err = listen.WriteToUDP([]byte("hello client"), addr)
                if err != nil {
                    fmt.Printf("write udp failed, err:%v\n", err)
                    continue
                }
            }
        }

        2.客户端流程

        package main
         
        import (
            "fmt"
            "net"
        )
         
        func main() {
            // 创建连接
            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()
            // 发送数据
            senddata := []byte("hello server!")
            _, err = socket.Write(senddata)
            if err != nil {
                fmt.Println("发送数据失败!", err)
                return
            }
            // 接收数据
            data := make([]byte, 4096)
            read, remoteAddr, err := socket.ReadFromUDP(data)
            if err != nil {
                fmt.Println("读取数据失败!", err)
                return
            }
            fmt.Println(read, remoteAddr)
            fmt.Printf("%s\n", data)
        }

        以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对易采站长站的支持。如果你想了解更多相关内容请查看下面相关链接