Rumah  >  Artikel  >  pembangunan bahagian belakang  >  golang ke hadapan tcp

golang ke hadapan tcp

WBOY
WBOYasal
2023-05-16 14:45:37717semak imbas

Mencipta dan mengurus sambungan TCP adalah sangat mudah dalam bahasa Go. Artikel ini akan memperkenalkan cara menggunakan bahasa Go untuk mencipta perkhidmatan TCP dan memajukan sambungan TCP.

  1. Pengetahuan prasyarat

Sebelum mempelajari artikel ini, anda perlu menguasai mata pengetahuan asas berikut:

  • Pengetahuan asas bahasa Go
  • Konsep asas dan penggunaan protokol TCP
  1. Mencipta perkhidmatan TCP

Mencipta perkhidmatan TCP dalam bahasa Go adalah sangat mudah. Mula-mula, kita perlu mengimport pakej net dan pakej bufio, kemudian gunakan kaedah net.Listen untuk mendengar nombor port:

package main

import (
    "bufio"
    "fmt"
    "net"
)

func main() {
    ln, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        return
    }
    defer ln.Close()
    fmt.Println("Listening on port 8080...")
}

Dalam contoh di atas, kami mendengar 8080 nombor port dan log masuk dalam konsol Output Listening on port 8080....

  1. Terima sambungan TCP

Seterusnya, kita perlu menerima sambungan TCP. Gunakan kaedah ln.Accept() untuk menyekat atur cara sehingga sambungan sedia. Sebaik sahaja terdapat permintaan sambungan, kami boleh membuat coroutine baharu untuk mengendalikan sambungan:

for {
    conn, err := ln.Accept()
    
    if err != nil {
        fmt.Println("Error accepting connection:", err.Error())
        return
    }
    fmt.Println("Connection accepted.")

    // 处理连接
    go handleConnection(conn)
}

func handleConnection(conn net.Conn) {
    // 处理连接
}

Dalam kod di atas, kami menggunakan gelung tak terhingga untuk terus menerima permintaan sambungan. Apabila terdapat permintaan sambungan, kami akan membuat coroutine baharu go handleConnection(conn) untuk mengendalikan sambungan.

  1. Mengendalikan sambungan TCP

Seterusnya, kita perlu memproses sambungan. Untuk setiap sambungan klien, kami perlu memajukan semua data yang dihantar oleh klien ke pelayan lain. Membaca dan menulis boleh dilakukan menggunakan pakej bufio.

func handleConnection(conn net.Conn) {
    defer conn.Close()
    
    remoteConn, err := net.Dial("tcp", "127.0.0.1:9090")
    if err != nil {
        fmt.Println("Error connecting to remote server:", err.Error())
        return
    }
    defer remoteConn.Close()

    go func() {
        defer conn.Close()
        defer remoteConn.Close()

        for {
            data, err := bufio.NewReader(conn).ReadString('
')
            if err != nil {
                fmt.Println("Error reading from conn:", err.Error())
                return
            }
            _, err = remoteConn.Write([]byte(data))
            if err != nil {
                fmt.Println("Error writing to remoteConn:", err.Error())
                return
            }
        }
    }()

    // 从remoteConn读取数据并转发到conn
    for {
        data, err := bufio.NewReader(remoteConn).ReadString('
')
        if err != nil {
            fmt.Println("Error reading from remoteConn:", err.Error())
            return
        }
        _, err = conn.Write([]byte(data))
        if err != nil {
            fmt.Println("Error writing to conn:", err.Error())
            return
        }
    }
}

Dalam kod di atas, kami mula-mula menggunakan kaedah net.Dial untuk menyambung ke pelayan lain, dan kemudian memulakan dua coroutine: satu coroutine membaca data yang dihantar oleh pelanggan dan memajukannya ke pelayan lain, Satu lagi coroutine membaca data daripada pelayan dan memajukannya kepada klien.

Perlu diambil perhatian bahawa defer conn.Close() dan defer remoteConn.Close() mesti digunakan dalam setiap coroutine untuk memastikan sambungan tidak akan ditutup secara tidak sengaja.

  1. Kod lengkap

Berikut ialah kod perkhidmatan pemajuan TCP lengkap:

package main

import (
    "bufio"
    "fmt"
    "net"
)

func main() {
    ln, err := net.Listen("tcp", ":8080")
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        return
    }
    defer ln.Close()
    fmt.Println("Listening on port 8080...")

    for {
        conn, err := ln.Accept()
        
        if err != nil {
            fmt.Println("Error accepting connection:", err.Error())
            return
        }
        fmt.Println("Connection accepted.")

        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    defer conn.Close()
    
    remoteConn, err := net.Dial("tcp", "127.0.0.1:9090")
    if err != nil {
        fmt.Println("Error connecting to remote server:", err.Error())
        return
    }
    defer remoteConn.Close()

    go func() {
        defer conn.Close()
        defer remoteConn.Close()

        for {
            data, err := bufio.NewReader(conn).ReadString('
')
            if err != nil {
                fmt.Println("Error reading from conn:", err.Error())
                return
            }
            _, err = remoteConn.Write([]byte(data))
            if err != nil {
                fmt.Println("Error writing to remoteConn:", err.Error())
                return
            }
        }
    }()

    for {
        data, err := bufio.NewReader(remoteConn).ReadString('
')
        if err != nil {
            fmt.Println("Error reading from remoteConn:", err.Error())
            return
        }
        _, err = conn.Write([]byte(data))
        if err != nil {
            fmt.Println("Error writing to conn:", err.Error())
            return
        }
    }
}
  1. Ringkasan

Pergi Bahasa menjadikan mencipta dan mengurus sambungan TCP menjadi mudah. Artikel ini memperkenalkan cara menggunakan bahasa Go untuk mencipta perkhidmatan TCP dan memajukannya, saya harap ia akan membantu anda.

Atas ialah kandungan terperinci golang ke hadapan tcp. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn