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)
}

原文地址:https://www.cnblogs.com/dcz2015/p/11235186.html