Backend Development
Golang
Go language: Tutorial to efficiently extract IP addresses from TCP connections
Go language: Tutorial to efficiently extract IP addresses from TCP connections

When doing network programming in Go language, we often need to deal with TCP connections. When a new TCP connection is received through the net.Listener.Accept() method, an object of the net.Conn interface type will be obtained. This interface provides the RemoteAddr() method to obtain the remote address of the connection. However, RemoteAddr() returns a net.Addr interface, which is a general network address interface and does not directly contain the IP address field. In order to get the pure IP address (without the port) we need to do some type casting and field access.
Core method: Extract IP address from TCP connection
The design of the Go language standard library allows us to safely access underlying concrete types through type assertions. For TCP connections, the underlying implementation of the net.Conn interface is usually *net.TCPConn, and the underlying implementation of the net.Addr interface returned by its RemoteAddr() method is *net.TCPAddr. The *net.TCPAddr structure contains IP and Port fields.
Therefore, a neat way to extract the pure IP address from a *net.TCPConn object is:
tcpconn.RemoteAddr().(*net.TCPAddr).IP
This expression breaks down as follows:
- tcpconn.RemoteAddr(): Call the RemoteAddr() method of the *net.TCPConn object and return a net.Addr interface.
- .(net.TCPAddr): Perform type assertion on the net.Addr interface and convert it to the specific *net.TCPAddr type. This is because we know that for TCP connections, the underlying type of the remote address is *net.TCPAddr.
- .IP: Access the IP field in the *net.TCPAddr structure. The type of this field is net.IP, which represents a pure IP address.
code example
To better understand the above process, let's create a simple TCP server that accepts client connections and prints out the client's plain IP address.
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
// 1. Start the TCP listener listener, err := net.Listen("tcp", "127.0.0.1:0") // Listen to all available local IPs, port 0 means the system automatically assigns if err != nil {
log.Fatalf("Unable to start listener: %v", err)
}
defer listener.Close()
fmt.Printf("The server is listening: %s\n", listener.Addr().String())
// 2. Start a goroutine as a client and connect to the server go func() {
time.Sleep(100 * time.Millisecond) // Wait for the server to completely start clientConn, err := net.Dial("tcp", listener.Addr().String())
if err != nil {
log.Printf("Client connection failed: %v", err)
return
}
defer clientConn.Close()
fmt.Println("The client has connected to the server.")
_, _ = clientConn.Write([]byte("Hello from client!")) // The client sends some data}()
// 3. The server accepts the client connection conn, err := listener.Accept()
if err != nil {
log.Fatalf("Failed to accept connection: %v", err)
}
defer conn.Close()
fmt.Printf("Server accepted connection from: %s\n", conn.RemoteAddr().String())
// Core: Extract pure IP address from net.Conn // First, assert net.Conn as *net.TCPConn
tcpConn, ok := conn.(*net.TCPConn)
if !ok {
log.Fatalf("The received connection is not of type *net.TCPConn")
}
// Get the remote address, it returns a net.Addr interface remoteAddr := tcpConn.RemoteAddr()
// Assert the net.Addr interface to *net.TCPAddr type tcpAddr, ok := remoteAddr.(*net.TCPAddr)
if !ok {
log.Fatalf("RemoteAddr is not *net.TCPAddr type")
}
//Extract IP address (net.IP type) from *net.TCPAddr
ipAddress := tcpAddr.IP
fmt.Printf("Pure IP address successfully extracted: %s\n", ipAddress.String())
fmt.Printf("IP address type: %T\n", ipAddress)
// Simulate reading client data buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
log.Printf("Failed to read client data: %v", err)
} else if n > 0 {
fmt.Printf("Server received data: %s\n", string(buf[:n]))
}
}
Run the above code and you will see that the server starts successfully, the client connects, and the server is able to accurately extract and print out the client's pure IP address.
Principle and analysis
- net.Conn interface : This is one of the most basic interfaces in Go network programming. It defines methods for reading and writing data and obtaining local/remote addresses. The Accept() method returns this interface type.
- net.Addr interface : Both the RemoteAddr() and LocalAddr() methods return the net.Addr interface. This interface is very general and only defines the Network() and String() methods. It cannot directly access the IP address or port.
- * ` net.TCPAddr specific type**: For TCP networks, the actual underlying type of the net.Addr interface is *net.TCPAddr`. This structure is defined as follows:
typeTCPAddr struct { IP IP Port int Zone string // IPv6 zone identifier }It explicitly contains the IP field (type net.IP) and the Port field (type int).
- Type assertion : .(Type) is the syntax for type assertion in Go language. It attempts to convert a value of an interface type to its underlying concrete type. It returns the converted value and true if the conversion is successful; if it fails, it returns a zero value and false. In our example, remoteAddr.(*net.TCPAddr) asserts the net.Addr interface as *net.TCPAddr.
- net.IP type : net.IP is actually a []byte slice, which can represent an IPv4 or IPv6 address. For example, IPv4 addresses are usually 4 bytes and IPv6 addresses are 16 bytes. It provides the String() method to easily convert it into string form.
Things to note
- Safety of type assertion : Although the net.Conn returned by net.Listener.Accept() is usually *net.TCPConn, and the net.Addr returned by RemoteAddr() is usually *net.TCPAddr, for the sake of code robustness, it is best to use the form of value, ok := interfaceValue.(Type) to check whether the assertion is successful. This avoids a runtime panic in the event of a type mismatch.
- Local address and remote address : RemoteAddr() is used to obtain the address of the other end of the connection (usually the client address), while LocalAddr() is used to obtain the address of the local connection (usually the server address). Choose the right method based on your needs.
- Characteristics of the net.IP object : net.IP is a byte slice. If you need to convert it to a string, use the ipAddress.String() method. If you need to check whether an IP address is IPv4 or IPv6, you can use the ipAddress.To4() or ipAddress.To16() method.
- Error handling : In actual network programming, operations such as net.Listen, net.Accept, net.Dial, etc. may return errors. It is important to handle these errors appropriately to ensure program stability and reliability.
Summarize
Obtaining the pure IP address from the *net.TCPConn object is a common need in Go network programming. By understanding the relationship between net.Conn, net.Addr and *net.TCPAddr and using the type assertion mechanism of the Go language, we can achieve this goal concisely and efficiently. The recommended approach is to use tcpconn.RemoteAddr().(*net.TCPAddr).IP, combined with error checking to ensure type assertion safety. Mastering this skill will help you manage network connection information more accurately.
The above is the detailed content of Go language: Tutorial to efficiently extract IP addresses from TCP connections. For more information, please follow other related articles on the PHP Chinese website!
Hot AI Tools
Undress AI Tool
Undress images for free
AI Clothes Remover
Online AI tool for removing clothes from photos.
Undresser.AI Undress
AI-powered app for creating realistic nude photos
ArtGPT
AI image generator for creative art from text prompts.
Stock Market GPT
AI powered investment research for smarter decisions
Hot Article
Popular tool
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
Hot Topics
20522
7
13634
4
How to apply the facade pattern (Facade) in Golang Go language simplifies the API of complex systems
Mar 10, 2026 pm 12:27 PM
The Facade should be used when the caller needs to write more than 5 lines of initialization, call more than 3 packages in sequence, and manually handle intermediate states; it should pass the interface rather than the specific type, provide 3 to 5 core methods, and enforce Shutdown() resource cleanup.
How to implement gRPC server-side streaming mode in Golang. Practical combat of real-time data streaming in Go language
Mar 10, 2026 am 10:21 AM
The server-side stream is a gRPC communication mode with a single request from the client and multiple responses from the server. It is suitable for "single push, multiple receive" scenarios such as real-time push and log pulling. The definition needs to declare rpcGetMetrics(MetricsRequest)returns(streamMetricsResponse) in .proto. The server-side implementation must call stream.Send() multiple times and avoid reusing the same instance. The client must loop Recv() and correctly handle io.EOF.
SQL performance analysis tool in Golang web development Go language GORM-Query-Logger
Mar 11, 2026 am 11:12 AM
GORM does not print complete SQL by default in order to prevent sensitive data from leaking and reduce log volume. It is necessary to customize the Logger and rewrite the LogMode and Info methods to splice sql.String() and sql.Variables to achieve parameterized output. SlowThreshold only counts the time spent on the GORM layer, and does not include network and database lock waits.
How to implement microservice configuration center hot update in Golang Go language Apollo configuration integration
Mar 10, 2026 am 10:52 AM
ApolloClient.GetConfig() cannot get the updated value because it does not monitor changes by default. You need to explicitly enable long polling (WithLongPolling(true)) and register the AddChangeListener callback. In the callback, deserialize the new configuration and use the atomic pointer to switch instances.
How to parse and generate CSV files in Golang Go language encoding/csv standard library tips
Mar 10, 2026 am 11:39 AM
csv.Reader defaults to ErrFieldCount instead of panic if the number of fields is inconsistent, but ignoring errors will cause subsequent panic; to tolerate fluctuations, FieldsPerRecord=-1 must be set; csv.Encoder does not handle encoding, and Chinese needs to be manually transcoded or add UTF-8BOM; ReadAll is prone to OOM, and loop Read should be used instead; configurations such as custom delimiters must be set before reading and writing for the first time.
How to use Dapr to build cloud-native microservices in Golang Go language Dapr SDK Development Guide
Mar 10, 2026 am 11:21 AM
The root cause is that the main goroutine is not blocked. dapr.Run() only registers the component and starts the service but does not block the main thread. You need to wait explicitly with select{} or signal.Notify; the business logic should be passed in as a callback or started in an independent goroutine.
How to configure Golang plug-in in VSCode Go language code completion and debugging environment optimization
Mar 10, 2026 am 11:36 AM
Go plug-in installed but not completed? Check whether gopls actually enables VSCode's Go plug-in (golang.go) which relies on gopls to provide semantic completion, jump and diagnosis by default. However, many people think that everything is fine after installing the plug-in - in fact, gopls may not be running at all. Common error phenomena: Ctrl Space only has basic syntax prompts and no field/method completion; F12 jump fails; no govet or staticcheck error is reported after saving. Open the command panel (Ctrl Shift P), run Go:Install/UpdateTools, check gopls and confirm the installation
How to operate Docker containers through API in Golang. Use of Go language Docker Client SDK
Mar 10, 2026 am 11:33 AM
HostConfig and NetworkingConfig need to be initialized explicitly; ContainerConfig.Image must be filled with the tagged image name; HostConfig.Mounts.Type must be lowercase; port mapping requires the cooperation of ExposedPorts and PortBindings; ContainerCreate returns the ID to indicate successful registration and can be started immediately; the log must be set to Follow=false and received with io.Copy; the exitcode should obtain the StatusCode through ContainerWait.





