我无法关闭侦听器,以便可以在同一端口重新打开它。我正在编写一个可热配置的代理服务器 - 即它的功能(重定向/块等)可以在运行中进行调整。代理在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)
}
但是,在尝试重新创建侦听器对象之前,我不知道如何等待并检查套接字是否已关闭?
答案 0 :(得分:-1)
好的,这远非完美,但我发现没有错误的唯一方法就是人为地延迟我的代码,以便套接字有时间关闭。 这并不是很好,因为它意味着代理在套接字关闭时停机2秒,但至少它不会出错。 如果有人有更好的解决方案,我希望听到它
func KillProxy() {
if listener != nil {
listener.Close()
log.Println("waiting for socket to close")
time.Sleep(2 * time.Second)
}
}