无法将*tls.listener转换为*net.TCPListener在golang上。

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

Cannot convert *tls.listener to *net.TCPListener on golang

问题

我在GO上创建了一个TLS服务器。

func main() {
    Log("Hello server!")

    cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        Log("server: loadkeys: ", err)
        return
    }

    config := tls.Config{Certificates: []tls.Certificate{cert}}
    config.Rand = rand.Reader
    service := "0.0.0.0:9988"
    listener, err := tls.Listen("tcp", service, &config)
    if err != nil {
        Log("server: listen: %s", err)
        return
    }

    defer listener.Close()

    for {
        Log("Waiting for clients")

        connection, error := listener.Accept()
        if error != nil {
            Log("Client error: ", error)
        } else {
            //connection.SetLinger(0) //这里出错
            go ClientHandler(connection)
        }
    }
}

我无法调用SetLinger函数,因为tls.Listen函数返回的是net.Listener类型,而我需要的是net.TCPListener类型。

我尝试了以下代码:

tpcListener := listener.(*net.TCPListener)

错误:panic: interface conversion: net.Listener is *tls.listener, not *net.TCPListener

net包中有ListenTCP函数,但在tls包中没有ListenTCP函数。

英文:

I created a TLS server on GO.

func main() {
	Log("Hello server!")
    
	cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        Log("server: loadkeys: ", err);
        return;
    }

    config := tls.Config{Certificates: []tls.Certificate{cert}}
	config.Rand = rand.Reader
    service := "0.0.0.0:9988"
    listener, err := tls.Listen("tcp", service, &config)
    if err != nil {
        Log("server: listen: %s", err)
        return
    }

    defer listener.Close()

	for {
		Log("Waiting for clients")

		connection, error := listener.Accept()
		if error != nil {
			Log("Client error: ", error)
		} else {
            //connection.SetLinger(0) //error here
			go ClientHandler(connection)
		}
	}
}

I cannot call SetLinger function, because tls.Listen function returns net.Listener. I need net.TCPListener.

I tried:

tpcListener := listener.(*net.TCPListener)

Error: panic: interface conversion: net.Listener is *tls.listener, not *net.TCPListener

There is ListenTCP on net package but there is not ListenTCP on tls package.

答案1

得分: 3

你明确提到了SetLinger,但是它是在TCPConn上调用的,而不是在TCPListener上调用的。你是否检查过接受的net.Conn是否可以断言为*net.TCPConn

crypto/tls包通过一个非导出类型实现了net.Listener接口,所以你无法以这种方式访问“内部”监听器。

如果你真的需要一个net.TCPListener
与所有其他提供方便函数为你创建监听器的Go标准包一样,有一些更底层的函数可以让你自己创建。所以调用net.ListenTCP,然后在它上面调用任何你喜欢的方法,然后通过tls.NewListener将其传递给tls包。
请参考crypto/tlsListen源代码以获取进一步的指导。

英文:

You explicitly mention SetLinger but that's called on a TCPConn not on a TCPListener. Have you checked if the accepted net.Conn can be asserted to *net.TCPConn?

<br>
The crypto/tls package implements the net.Listener interface via a non-exported type so you cannot access the "inner" listener that way.

If you really need a net.TCPListener:
As with all the other Go standard packages that provide convenience functions that create listeners for you, there are lower level functions that let you create your own. So call net.ListenTCP, then whatever methods you like on it, then pass that to the tls package via tls.NewListener.
See the source for crypto/tls's Listen for further guidance.

huangapple
  • 本文由 发表于 2015年10月11日 23:52:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/33066946.html
匿名

发表评论

匿名网友

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

确定