当前位置: 首页 > 知识库问答 >
问题:

TCP连接池

纪勇军
2023-03-14

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

编辑:我了解到tcp总是流0s,如果我在消息之前发送字节(1),这样我就可以使用刷新功能在新调用之前检查套接字是否为空。

共有1个答案

宦翔
2023-03-14

您的帖子实际上提出了几个问题:

  • 如何管理连接池
  • 如何处理套接字上的通信

这实际上是两件不同的事情。连接池只是管理一组连接的一种方式。实现这一点的一种简单方法是使用一个类,例如:

    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外部的连接,可能会泄漏连接。关闭()。例如,如果您想拥有一个活动池和非活动池,可以跟踪它们,这将解决此问题。

您可能还需要向池实现中添加一些其他内容:

  • 线程保护(例如使用sync.Mutex)

建立连接后,您可以正常调用读取和写入。要刷新套接字上的所有未处理数据,您只需使用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()返回错误接口,而不是网络。错误接口,我们需要后者能够轻松找出调用是否由于超时而返回。

 类似资料:
  • 问题内容: 这是我的代码: 输出量 为什么和具有相同的地址?在TCP中,我认为为新连接创建了一个新套接字。 问题答案: 这让我困惑了一秒钟,但这是正确的。确实创建了一个新的套接字(具有唯一的本地+远程地址元组)。维基百科的这段引文很好地描述了它: 服务器可以使用相同的本地端口号和本地IP地址创建多个同时建立的TCP套接字,每个套接字都映射到其自己的服务器子进程,并为自己的客户端进程提供服务。由于远

  • 提前致谢

  • 在套接字最终接受另一端消失的情况下,什么指定了这个超时?是操作系统(Ubuntu 11.04),还是来自TCP/IP规范,还是套接字配置选项?

  • 下面是我到目前为止的代码: 有人能解释一下在和情况下我该做什么吗?以及如何知道网络已断开并重新连接?

  • 我在Python中使用套接字制作聊天应用程序,但当我尝试从不同的计算机连接时,它会说: C:\用户\James\OneDrive\Documents\Python\Projects\Gui聊天\client.pyw[WinError 10060]连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机没有响应 这是套接字的服务器代码: 我还有一个循环接受所有请求: 在客

  • 问题内容: 在Go中,TCP连接(net.Conn)是io.ReadWriteCloser。我想通过模拟TCP连接来测试我的网络代码。我有两个要求: 要读取的数据存储在字符串中 每当写入数据时,我都希望将其存储在某种缓冲区中,以便以后使用 是否有数据结构或简单的方法? 问题答案: 为什么不使用?它是一种并且具有获取存储数据的方法。如果需要将其设置为,则可以定义自己的类型: 并定义一个方法: