Golang close net listener

时间:2015-06-20 09:52:52

标签: go proxy listener goroutine

我无法关闭侦听器,以便可以在同一端口重新打开它。我正在编写一个可热配置的代理服务器 - 即它的功能(重定向/块等)可以在运行中进行调整。代理在go例程中运行。我遇到的问题是当我重新配置监听器和代理时,监听器仍在使用先前配置中的端口。 (FYI监听器是全局指针) 我尝试过这样的事情:

杀死听众:

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)

然而,这似乎不起作用 - 我得到错误:

  

监听器(S1):

     

错误:listen tcp 0.0.0.0:8080:bind:地址已在使用中

     

监听器(S2):0xc2080015e0

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

  

panic:运行时错误:内存地址无效或nil指针取消引用

编辑回应JIM:

有趣的指针。好。我没有处理等待套接字关闭,我不知道应该怎么做。我正在使用的代理库就是这个: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)
    }    

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

1 个答案:

答案 0 :(得分:-1)

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

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