Golang 关闭网络监听器

标签 go proxy listener goroutine

我无法关闭监听器以便在同一端口上重新打开它。我正在编写一个可热配置的代理服务器 - 即它的作用(重定向/阻止等)可以动态调整。代理在 go 例程中运行。我遇到的问题是,当我重新配置监听器和代理时,监听器仍在使用先前配置中的那个端口。 (仅供引用,监听器是一个全局指针) 我正在尝试类似的东西:

杀死听众:

func KillProxy() {
    
    if listener != nil {
        log.Println(" *** TRYING TO STOP THE PROXY SERVER")
        (*listener).Close()
        listener = nil
    }
}

在重新配置之前:

log.Println("listener (S1): ", listener)
if listener == nil {
    // Start the listener to listen on the connection.
    l, err := net.Listen(CONN_TYPE, CONN_HOST + ":" + CONN_PORT)

    if err != nil {
        log.Println("error here: ", err)
    }    
    listener = &l //set it as a pointer to the newly created listener
} 
log.Println("listener (S2): ", listener)

但是这似乎不起作用 - 我收到错误:

listener (S1):

error here: listen tcp 0.0.0.0:8080: bind: address already in use

listener (S2): 0xc2080015e0

然后是一个巨大的堆栈跟踪,总结为:

panic: runtime error: invalid memory address or nil pointer dereference

编辑以回应吉姆:

有趣的重新指针。好的。我没有处理等待套接字关闭,我不确定应该怎么做。我使用的代理库是这个:https://github.com/abourget/goproxy .事情发生的顺序是:

KillProxy()
refreshProxy()

refreshProxy 包含上面发布的代码,该代码试图重新调整监听器的用途。 refreshProxy() 中发生的最后一件事是:

go http.Serve(*listener, proxy)

因此,如果我将监听器恢复为全局变量,而不是指针,我可以制作 KillProxy():

func KillProxy() {
    if listener != nil {
        listener.Close()
        listener = nil
    }
}

然后再次将监听器设置为

listener, err := net.Listen(CONN_TYPE, CONN_HOST + ":" + CONN_PORT) 
    if err != nil {
        log.Println("error here: ", err)
    }    

但是我不知道如何在尝试重新创建监听器对象之前等待并检查套接字是否已关闭?

最佳答案

好吧,这远非完美,但我发现唯一不让它出错的方法是在我的代码中人为地延迟,以便套接字有时间关闭。 这不是很好,因为它意味着在套接字关闭时代理关闭 2 秒,但至少它不会出错。 如果有人有更好的解决方案,我想听听

func KillProxy() {
    if listener != nil {
        listener.Close()
        log.Println("waiting for socket to close")
        time.Sleep(2 * time.Second)
    }
}

关于Golang 关闭网络监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30952623/

相关文章:

java - Eclipse : edittext changed listener , edittext 长度到微调项目

java - 如何让 JMS 消息监听器无限期地监听

java - 在 Java 中为 JTextField 显示事件?

go - 为什么 DeepEqual 对于 [...]int{0} 与 golang 中的 make([]int, 1, 1) 失败?有其他选择吗?

java - 将 JVM/JRE 设置为自动使用 Windows 代理

Python:使用带有请求的代理服务器的 HTTPS

php - 使用 php 代理的跨域 Ajax GET 请求

go - 我正在尝试将 Cobra 集成到我的程序中

go - 无法从 go 运行 C 调用

json - Protocol Buffer 格式的匿名结构