• Go语言实现简单的TCP、UDP链接


    ⼀、使用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
    ", 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
    ", 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
    ", err)
            return
        }
    
        fmt.Println("Conn Established...:")
    
        //读入输入的信息
        reader := bufio.NewReader(os.Stdin)
        for {
            data, err := reader.ReadString('
    ')
            if err != nil {
                fmt.Printf("read from console failed, err:%v
    ", err)
                break
            }
    
            data = strings.TrimSpace(data)
            //传输数据到服务端
            _, err = conn.Write([]byte(data))
            if err != nil {
                fmt.Printf("write failed, err:%v
    ", err)
                break
            }
        }
    }
    
    执⾏⼀下:
    客户端:
    服务端: 

    ⼆、使用Golang创建⼀个HTTP连接
    A.HTTP协议是基于TCP协议之上的⽂本协议。
    B.每行⽂本使⽤ 结尾,当连续两个 时,表示整个数据包结束。
    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
    ", err)
            return
        }
    
        data := "GET / HTTP/1.1
    "
        data += "HOST: www.baidu.com
    "
        data += "connection: close
    "
        data += "
    
    "
    
        //写入数据
        _, err = io.WriteString(conn, data)
        if err != nil {
            fmt.Printf("wirte string failed, err:%v
    ", 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
    ", err)
            return
        }
    
        for {
            var data [1024]byte
            //读取UDP数据
            count, addr, err := listen.ReadFromUDP(data[:])
            if err != nil {
                fmt.Printf("read udp failed, err:%v
    ", err)
                continue
            }
    
            fmt.Printf("data:%s addr:%v count:%d
    ", string(data[0:count]), addr, count)
            //返回数据
            _, err = listen.WriteToUDP([]byte("hello client"), addr)
            if err != nil {
                fmt.Printf("write udp failed, err:%v
    ", 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
    ", data)
    }
    

  • 相关阅读:
    一个疑难杂症 IIS URL区分大小写(FF的自动变换URL问题)?
    炉石传说 C# 设计文档(序)
    炉石传说 C# 开发笔记(BS上线尝试)
    炉石传说 C# 开发笔记(BS模式Demo)
    炉石传说 C# 开发笔记(6月底小结)
    炉石传说 C# 开发笔记 (初版)
    使用python+requests实现接口自动化测试
    SpringMVC之数据传递二
    SpringMVC之数据传递一
    SpringMVC之HandlerMapping的使用
  • 原文地址:https://www.cnblogs.com/dcz2015/p/11235186.html
Copyright © 2020-2023  润新知