Home  >  Article  >  Backend Development  >  golang forward tcp

golang forward tcp

WBOY
WBOYOriginal
2023-05-16 14:45:37629browse

It is very easy to create and manage TCP connections in Go language. This article will introduce how to use Go language to create a TCP service and forward TCP connections.

  1. Prerequisite knowledge

Before studying this article, you need to master the following basic knowledge points:

  • Go language basic knowledge
  • Basic concepts and usage of TCP protocol
  1. Creating TCP service

Creating TCP service in Go language is very simple. First, we need to import the net package and the bufio package, and then use the net.Listen method to listen to a port number:

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

in the above In the example, we listened to the 8080 port number and output Listening on port 8080... on the console.

  1. Accept TCP connections

Next, we need to accept TCP connections. Use the ln.Accept() method to block the program before a connection is ready. Once there is a connection request, we can create a new coroutine to handle the connection:

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

In the above code, we use an infinite loop to continuously accept connection requests. When there is a connection request, we will create a new coroutine go handleConnection(conn) to handle the connection.

  1. Processing TCP connections

Next, we need to process the connection. For each client connection, we need to forward all data sent by the client to another server. Reading and writing can be done using the bufio package.

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

In the above code, we first use the net.Dial method to connect to another server, and then start two coroutines: one coroutine reads the data sent by the client and Forwarded to another server, another coroutine reads data from the server and forwards it to the client.

It should be noted that defer conn.Close() and defer remoteConn.Close() must be used in each coroutine to ensure that the connection will not was unexpectedly closed.

  1. Complete code

The following is the complete TCP forwarding service code:

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. Summary

Go The language makes creating and managing TCP connections a breeze. This article introduces how to use Go language to create a TCP service and forward it. I hope it will be helpful to you.

The above is the detailed content of golang forward tcp. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn