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

 更新时间:2022年07月25日 08:34:16   作者:奋斗的大橙子  
这篇文章介绍了Go语言实现UDP协议及TCP通讯的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

⼀、使用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)
}

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

相关文章

  • GoLang日志监控系统实现

    GoLang日志监控系统实现

    这篇文章主要介绍了GoLang日志监控系统的实现流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • go之如何设置GOROOT和GOPATH

    go之如何设置GOROOT和GOPATH

    这篇文章主要介绍了go之如何设置GOROOT和GOPATH问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • go slice 扩容实现原理源码解析

    go slice 扩容实现原理源码解析

    这篇文章主要为大家介绍了go slice 扩容实现原理源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Go unsafe 包的使用详解

    Go unsafe 包的使用详解

    这篇文章主要介绍了Go unsafe 包的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Go语言中slice作为参数传递时遇到的一些“坑”

    Go语言中slice作为参数传递时遇到的一些“坑”

    这篇文章主要给大家介绍了关于Go语言中slice作为参数传递时遇到的一些“坑”,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)

    golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)

    在项目开发过程中,当操作一些用户的隐私信息,本文主要主要介绍了golang常用加密解密算法总结(AES、DES、RSA、Sha1MD5),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 详解go mod 使用方法

    详解go mod 使用方法

    golang 提供了 go mod命令来管理包,是go的一个模块管理工具,用来代替传统的GOPATH方案,本文给大家介绍go mod 使用方法,感兴趣的朋友一起看看吧
    2022-05-05
  • uber go zap 日志框架支持异步日志输出

    uber go zap 日志框架支持异步日志输出

    这篇文章主要为大家介绍了uber go zap 日志框架支持异步日志输出示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • go语言变量定义用法实例

    go语言变量定义用法实例

    这篇文章主要介绍了go语言变量定义用法,实例分析了go语言变量的定义及使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • axios gin的GET和POST请求实现示例

    axios gin的GET和POST请求实现示例

    这篇文章主要为大家介绍了axios gin的GET和POST请求实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04

最新评论