gpt4 book ai didi

TCP连接池

转载 作者:IT王子 更新时间:2023-10-29 01:18:54 28 4
gpt4 key购买 nike

我是套接字的新手,正在尝试通过 tcp 套接字创建连接池。我的实现发送 32 位长度,然后为每次调用发送二进制消息。但我有时会遇到问题,有时读者会收到来自服务器的先前响应(可能发生在客户端关闭并重新建立发送错误套接字时)。我如何在新请求之前刷新套接字(上次调用的剩余字节)。有什么建议吗?

编辑:我了解到 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() 之外的连接来泄漏连接。例如,如果您想持有一个活跃和不活跃的池,就可以跟踪它们,这将解决这个问题。

您可能希望添加到池化实现中的一些其他内容:

  • 线程保护(例如使用 sync.Mutex)
  • 在闲置一段时间后关闭空闲池中的连接
  • 错误检查以确保关闭的连接仍然有效

建立连接后,就可以正常调用 Read 和 Write 了。要刷新套接字上所有未完成的数据,您可以简单地使用 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 接口(interface),而不是 net.Error 接口(interface),我们需要后者能够轻松查明调用是否因超时而返回。

关于TCP连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10308388/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com