Go网络监听器关闭和例程处理

huangapple go评论80阅读模式
英文:

Go net listener closing and routine handling

问题

我正在启动一个例程并在一个网络监听器(HTTP)上进行监听。我想关闭监听器,关闭例程,然后启动一个新的例程并重新启动监听器。但是当我关闭监听器时,一切都乱了套。

listener 是全局变量)

listener, _ = net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
go PassThrough()

其中

func PassThrough() {
    verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
    flag.Parse()
    proxy := goproxy.NewProxyHttpServer()
    proxy.Verbose = *verbose
    log.Fatal(http.Serve(listener, proxy))
}

这样可以工作,但是如果我想停止 PassThrough() 并将监听器重新应用于不同的任务(例如不同的代理 "job"),使用 listener.Close() 关闭监听器会导致在尝试重新监听并调用新的例程时出错。

我得到以下错误:

ProxyControllers.go:146: accept tcp 127.0.0.1:8080: use of closed network connection
reverseproxy.go:141: http: proxy error: EOF

当我尝试重用监听器时。

我认为当我关闭监听器时,我需要告诉例程自己关闭。我正在使用 goproxy 库。

英文:

I am starting a routine and listening on a net listener (HTTP). I want to close the listener, close the routine and start a new routine, and restart the listener. When I close the listener all hell breaks loose.

(listener is global)

listener, _ = net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
go PassThrough()

where

func PassThrough() {
    verbose := flag.Bool("v", false, "should every proxy request be logged to stdout")
    flag.Parse()
    proxy := goproxy.NewProxyHttpServer()
    proxy.Verbose = *verbose
	log.Fatal(http.Serve(listener, proxy))
}

So this works but if I want to stop passThrough() and re apply the listener to a different task (for instance a different proxy "job") closing the listener with listener.Close() causes it to break when I then try to re Listen and call a new go routine.

I get the error:

ProxyControllers.go:146: accept tcp 127.0.0.1:8080: use of closed network connection
reverseproxy.go:141: http: proxy error: EOF

When I then try to reuse the Listener.

I think I need to tell the routine to close itself down somehow when i Close() the listener?

Im using the goproxy library

答案1

得分: 1

  1. 标志应该只被解析一次,最好在一个init函数中解析。
  2. 你不能重用一个监听器,你需要再次调用Listen
  3. 不要调用log.Fatal,那会终止你的程序。

示例:

var verbose = flag.Bool("v", false, "是否将每个代理请求记录到标准输出")

func runProxy(typ, host, port string) (listener tcp.Listener) {
    listener, _ = net.Listen(typ, host+":"+port)
    proxy := goproxy.NewProxyHttpServer()
    proxy.Verbose = *verbose

    go http.Serve(listener, proxy) // 你可以忽略这个错误
    return
}

func main() {
    flag.Parse()
    l := runProxy(....)
    // 做一些事情
    l.Close()
    l = runProxy(....)
    //....
}
英文:
  1. Flags should only be parsed once and probably in an init func.
  2. You can't reuse a listener, you will have to call Listen again.
  3. Don't call log.Fatal, that will terminate your program.

Example:

var verbose = flag.Bool("v", false, "should every proxy request be logged to stdout")

func runProxy(typ, host, port string) (listener tcp.Listener) {
	listener, _ = net.Listen(typ, host+":"+port)
	proxy := goproxy.NewProxyHttpServer()
	proxy.Verbose = *verbose

	go http.Serve(listener, proxy) // you can probably ignore this error
	return
}

func main() {
	flag.Parse()
	l := runProxy(....)
	//do something
	l.Close()
	l = runProxy(....)
	//....
}

huangapple
  • 本文由 发表于 2015年5月21日 01:22:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/30356395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定