我是新来的套接字,并尝试通过TCP套接字创建连接池。我的实现发送32位长度,然后为每个呼叫发送二进制消息。但我有时遇到问题,有时读者从服务器接收以前的响应(可能发生在客户端关闭并在发送错误时重新建立套接字)。如何在新请求之前刷新套接字(前一个调用的剩余字节)。任何建议?TCP连接池
编辑:我知道tcp总是流0,如果我发送消息之前的字节(1),所以我可以有一个刷新函数来检查新的调用之前,套接字不是空的。
我是新来的套接字,并尝试通过TCP套接字创建连接池。我的实现发送32位长度,然后为每个呼叫发送二进制消息。但我有时遇到问题,有时读者从服务器接收以前的响应(可能发生在客户端关闭并在发送错误时重新建立套接字)。如何在新请求之前刷新套接字(前一个调用的剩余字节)。任何建议?TCP连接池
编辑:我知道tcp总是流0,如果我发送消息之前的字节(1),所以我可以有一个刷新函数来检查新的调用之前,套接字不是空的。
文章实际问几个问题:
这些实际上是两回事。连接池只是管理一组连接的一种方式。实现一个简单的方法是使用一类如:
package netpool
import (
"net"
)
const MaxConnections = 3
type Error string
func (e Error) Error() string {
return string(e)
}
var ErrMaxConn = Error("Maximum connections reached")
type Netpool struct {
name string
conns int
free []net.Conn
}
func NewNetpool(name string) *Netpool {
return &Netpool{
name: name,
}
}
func (n *Netpool) Open() (conn net.Conn, err error) {
if n.conns >= MaxConnections && len(n.free) == 0 {
return nil, ErrMaxConn
}
if len(n.free) > 0 {
// return the first free connection in the pool
conn = n.free[0]
n.free = n.free[1:]
} else {
addr, err := net.ResolveTCPAddr("tcp", n.name)
if err != nil {
return nil, err
}
conn, err = net.DialTCP("tcp", nil, addr)
if err != nil {
return nil, err
}
n.conns += 1
}
return conn, err
}
func (n *Netpool) Close(conn net.Conn) error {
n.free = append(n.free, conn)
return nil
}
我创建了一个独立的类在这里。它通常会作为MyHTTPHost或MyDatabase等更高级别类的一部分来实现。
在这个简单的实现中,不会跟踪通过netpool.Open()返回的连接。可以通过调用Open()来泄漏连接,然后关闭netpool.Close()之外的连接。例如,如果要保存活动和非活动池,可以跟踪它们,这可以解决此问题。
一对夫妇的其他东西,你可能要添加到池的实现:
一旦你有一个连接,你可以调用正常读写就可以了。要清除套接字上的所有未完成数据,只需使用ioutil.ReadAll()辅助函数即可。默认情况下,如果没有可用的数据,它将无限期地阻塞。为了避免这种情况,使用添加读取超时:
conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond))
_, err = ioutil.ReadAll(conn)
neterr, ok := err.(net.Error)
if ok && neterr.Timeout() {
err = nil // timeout isn't an error in this case
}
if err != nil {
// handle the error case.
}
如果有正在等待这将从给定的连接读取所有数据,如果没有数据待处理500毫秒后,将返回一个I/O超时错误。
类型声明是必需的,因为ioutil.ReadAll()返回一个Error接口,而不是一个net.Error接口,我们需要后者能够轻松地找出是否由于超时而返回调用。
只是一个想法...或者open()需要MaxConnections(1)类型的实际最大连接数和一个最大连接池数;或者(2)删除顶部的if并允许尽可能多的连接,只有在池满后才能正确关闭它们。 – Richard 2015-04-08 12:12:32
欢迎来到SO!如果你能显示一些你的代码,那将是非常棒的。 – vyegorov 2012-04-25 19:20:38