Maison  >  Article  >  développement back-end  >  Golang avant TCP

Golang avant TCP

WBOY
WBOYoriginal
2023-05-16 14:45:37628parcourir

Créer et gérer des connexions TCP est très simple en langage Go. Cet article explique comment utiliser le langage Go pour créer un service TCP et transférer les connexions TCP.

  1. Connaissances préalables

Avant d'étudier cet article, vous devez maîtriser les points de connaissances de base suivants :

  • Connaissance de base du langage Go
  • Concepts de base et utilisation du protocole TCP
  1. Création de services TCP

En langage Go Créer un service TCP est très simple. Tout d'abord, nous devons importer le package net et le package bufio, puis utiliser la méthode net.Listen pour écouter un numéro de port : net包和bufio包,然后使用net.Listen方法监听一个端口号:

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

在上面的例子中,我们监听了8080端口号,并在控制台输出Listening on port 8080...

  1. 接受TCP连接

接下来,我们需要接受TCP连接。使用ln.Accept()方法可以在一个连接准备好之前阻塞程序。一旦有一个连接请求,我们就可以创建一个新协程,处理连接:

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) {
    // 处理连接
}

在上面的代码中,我们使用了一个无限循环来不断接受连接请求。当有连接请求时,我们会创建一个新的协程go handleConnection(conn)来处理连接。

  1. 处理TCP连接

接下来,我们需要对连接进行处理。对于每个客户端连接,我们需要将客户端发送的所有数据转发到另一个服务器上。可以使用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
        }
    }
}

上面的代码中,我们首先使用net.Dial方法连接到另一个服务器,然后开启两个协程:一个协程读取客户端发来的数据并转发给另一个服务器,另一个协程从服务器读取数据并转发给客户端。

需要注意的是,在每个协程中都要使用defer conn.Close()defer remoteConn.Close()

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

Dans l'exemple ci-dessus, nous avons écouté le numéro de port 8080 et affiché Écoute sur le port 8080... sur la console.
    1. Accepter les connexions TCP

    Ensuite, nous devons accepter les connexions TCP. Utilisez la méthode ln.Accept() pour bloquer le programme jusqu'à ce qu'une connexion soit prête. Une fois qu'il y a une demande de connexion, nous pouvons créer une nouvelle coroutine pour gérer la connexion :

    rrreee
      Dans le code ci-dessus, nous utilisons une boucle infinie pour accepter en continu les demandes de connexion. Lorsqu'il y a une demande de connexion, nous créerons une nouvelle coroutine go handleConnection(conn) pour gérer la connexion.
      1. Gestion des connexions TCP

      Ensuite, nous devons traiter la connexion. Pour chaque connexion client, nous devons transmettre toutes les données envoyées par le client vers un autre serveur. Vous pouvez utiliser le package bufio pour la lecture et l'écriture. 🎜rrreee🎜Dans le code ci-dessus, nous utilisons d'abord la méthode net.Dial pour nous connecter à un autre serveur, puis démarrons deux coroutines : une coroutine lit les données envoyées par le client et les transmet à l'autre Un serveur, une autre coroutine lit les données du serveur et les transmet au client. 🎜🎜Il convient de noter que defer conn.Close() et defer remoteConn.Close() doivent être utilisés dans chaque coroutine pour garantir que la connexion ne sera pas fermée accidentellement . 🎜🎜🎜Code complet🎜🎜🎜Voici le code complet du service de transfert TCP : 🎜rrreee🎜🎜Résumé🎜🎜🎜Le langage Go facilite la création et la gestion des connexions TCP. Cet article explique comment utiliser le langage Go pour créer un service TCP et le transmettre. J'espère qu'il vous sera utile. 🎜

    Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration:
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn