Go socket

Go socket

什么是socket

Socket起源于Unix,而Unix基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关

闭close”模式来操作。Socket就是该模式的一个实现,网络的Socket数据传输是一种特殊的I/O,Socket也

是一种文件描述符。Socket也具有一个类似于打开文件的函数调用:Socket(),该函数返回一个整型的

Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。

常用的Socket类型有两种:流式Socket( SOCK_STREAM) 和数据报式Socket( SOCK_DGRAM) 。流

式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,

对应于无连接的UDP服务应用。

TCP 连接

服务端

package main

import (
    "fmt"
    "io/ioutil"
    "net"
)

func main() {
    service := ":3000"
    tcpAddr, _ := net.ResolveTCPAddr("tcp4", service)
    listen, _ := net.ListenTCP("tcp", tcpAddr)
    for {
        conn, err := listen.Accept()
        if err != nil {
            continue
        }
        result, _ := ioutil.ReadAll(conn)
        fmt.Println(string(result))
        conn.Close()
    }
}

客户端

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    service := "127.0.0.1:3000"
    tdpAddr, _ := net.ResolveTCPAddr("tcp4", service)
    conn, _ := net.DialTCP("tcp", nil, tdpAddr)
    conn.Write([]byte("Hello World"))
}

多协程服务端

package main

import (
    "net"
    "time"
)

func main() {
    service := ":3000"
    tcpAddr, _ := net.ResolveTCPAddr("tcp4", service)
    listen, _ := net.ListenTCP("tcp", tcpAddr)
    for {
        conn, err := listen.Accept()
        if err != nil {
            continue
        }
        go handlenClient(conn)
    }
}

func handlenClient(conn net.Conn) {
    conn.SetReadDeadline(time.Now().Add(2 * time.Minute)) // set 2 minute timeout
    request := make([]byte, 128)
    defer conn.Close()
    for {
        _, err := conn.Read(request)
        if err != nil {
            break
        }

        conn.Write([]byte("Hello World"))

        request = make([]byte, 128)
    }
}

UDP连接

服务端

func main() {
    service := ":3000"
    addr, _ := net.ResolveUDPAddr("udp4", service)
    conn, _ := net.ListenUDP("udp", addr)
    for {
        handlenClient(conn)
    }
}

func handlenClient(conn *net.UDPConn) {
    var buf [512]byte
    n, addr, _ := conn.ReadFromUDP(buf[0:])
    daytime := time.Now().String()
    fmt.Println(string(buf[0:n]))
    conn.WriteToUDP([]byte(daytime), addr)
}

客户端

func main() {
    service := "127.0.0.1:3000"
    addr, _ := net.ResolveUDPAddr("udp4", service)
    conn, _ := net.DialUDP("udp4", nil, addr)
    conn.Write([]byte("Hello World"))
    var buf [512]byte
    n, _ := conn.Read(buf[0:])
    fmt.Println(string(buf[0:n]))
}

socket ssl 加密

[生成自签证书](https://www.cnblogs.com/lihuang/articles/4205540.html\

服务端

package main

import (
    "crypto/rand"
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "time"
)

func main() {
    service := "www.demo.com:3000"
    cert, _ := tls.LoadX509KeyPair("./file/server.crt", "./file/server.key")
    config := tls.Config{Certificates:[]tls.Certificate{cert}}
    config.Time = time.Now
    config.Rand = rand.Reader
    listen, _ := tls.Listen("tcp", service, &config)
    for {
        conn, err := listen.Accept()
        if err != nil {
            continue
        }
        result, _ := ioutil.ReadAll(conn)
        fmt.Println(string(result))
        conn.Close()
    }
}

客户端

package main

import (
    "crypto/tls"
    "fmt"
    "github.com/gpmgo/gopm/modules/log"
    "io"
)

func main() {
    service := "www.demo.com:3000"
    conn, err := tls.Dial("tcp", service, nil)
    if err != nil {
        log.Fatal(err.Error())
    }
    defer conn.Close()
    state := conn.ConnectionState()
    fmt.Println(state)
    io.WriteString(conn, "Hello!")
}

Last updated

Was this helpful?