怎么获取客户端真实IP?GO

在使用 Golang 的 net/rpc 包进行 RPC 服务开发时,我们有时候会遇到需要获取客户端的真实 IP 和当前连接 net.Conn 的需求。然而在 net/rpc 的服务处理方法中,并没有提供直接获取到这些信息的途径。

那么,我们应该如何去获取这些信息呢?实现这个功能会有一些复杂,因为RPC的默认处理器没有提供获取net.Conn连接对象的接口。我们需要自定义RPC的编解码器和处理器来获得这些信息。以下是我的解决方案:

首先,我们要创建一个新的RPC服务处理器:

type serverCodec struct {
	rwc    io.ReadWriteCloser
	dec    *gob.Decoder // for reading JSON values
	enc    *gob.Encoder // for writing JSON values
	encBuf *bufio.Writer
	conn   net.Conn
}

func (c *serverCodec) ReadRequestHeader(r *rpc.Request) error {
	err := c.dec.Decode(r)
	if err != nil {
		return err
	}
	return nil
}

func (c *serverCodec) ReadRequestBody(body interface{}) error {
	return c.dec.Decode(body)
}

func (c *serverCodec) WriteResponse(resp *rpc.Response, body interface{}) error {
	err := c.enc.Encode(resp)
	if err != nil {
		return err
	}
	err = c.enc.Encode(body)
	if err != nil {
		return err
	}
	return c.encBuf.Flush()
}

func (c *serverCodec) Close() error {
	c.encBuf.Flush()
	return c.rwc.Close()
}

func NewServerCodec(conn net.Conn) rpc.ServerCodec {
	buf := bufio.NewWriter(conn)
	return &serverCodec{
		rwc:    conn,
		dec:    gob.NewDecoder(conn),
		enc:    gob.NewEncoder(buf),
		encBuf: buf,
		conn:   conn,
	}
}

上面的代码创建了一个符合rpc.ServerCodec接口的新的编解码器。该编解码器在处理请求和响应时会获取到当前的net.Conn连接。

然后我们需要自定义我们的RPC服务,使其在处理请求时能够使用自定义的编解码器。

func main() {
    // Create an instance of the MathService
    mathService := new(MathService)
    // Register MathService for RPC
    rpc.Register(mathService)
    // Create a TCP listener
    listener, err := net.Listen("tcp", "0.0.0.0:1234")
    if err != nil {
        fmt.Println("Error starting server:", err)
        return
    }
    defer listener.Close()
    fmt.Println("Server listening on :1234")
    for {
        // Accept incoming connections
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("Error accepting connection:", err)
            continue
        }
        // Use our custom codec to Serve the connection in a new goroutine
        go rpc.ServeCodec(NewServerCodec(conn))
    }
}

这样,我们的RPC服务就会使用自定义的编解码器来处理每一个请求,每一个连接对应一个编解码器,我们可以从编解码器中获取到连接信息。

需要注意的是,在我们的服务方法中,我们依然不能直接获得该连接信息,我们需要在方法被调用之前或之后去获取。具体的实现方式可能需要你再进行一些代码的修改和调整。但是希望以上的内容能够帮助你解决这个问题。

相关推荐

  1. 怎么获取客户真实IP?GO

    2024-01-02 08:02:01       61 阅读
  2. FRP + nginx 获取客户真实IP

    2024-01-02 08:02:01       69 阅读
  3. Nginx(二十) 获取真实客户IP

    2024-01-02 08:02:01       43 阅读
  4. 解决 docker swarm 节点容器无法获取客户真实IP

    2024-01-02 08:02:01       39 阅读
  5. 获取客户(前端)IP地址

    2024-01-02 08:02:01       23 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-02 08:02:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-02 08:02:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-02 08:02:01       82 阅读
  4. Python语言-面向对象

    2024-01-02 08:02:01       91 阅读

热门阅读

  1. django静态文件命名空间

    2024-01-02 08:02:01       58 阅读
  2. Django通用视图

    2024-01-02 08:02:01       51 阅读
  3. iostat获取IO延迟单位从ms调整us的方案

    2024-01-02 08:02:01       57 阅读
  4. 微信小程序如何分包管理

    2024-01-02 08:02:01       55 阅读
  5. 11.2 Screen调试实战(二,运行时阶段)

    2024-01-02 08:02:01       58 阅读
  6. K8S学习指南(55)-K8S核心组件Controller-Manager简介

    2024-01-02 08:02:01       52 阅读
  7. 【python爬虫】xpath使用说明

    2024-01-02 08:02:01       59 阅读
  8. 数据结构OJ实验13-动态查找

    2024-01-02 08:02:01       40 阅读
  9. PDF模板填充,基于IText5(改进版)

    2024-01-02 08:02:01       55 阅读
  10. Avalonia框架下实现热更新

    2024-01-02 08:02:01       53 阅读