Golang tcp套接字读取最终给出EOF

atmip9wb  于 2023-08-01  发布在  Go
关注(0)|答案(3)|浏览(206)

从套接字阅读时遇到问题。有一个asterisk示例运行着大量的调用(一分钟10-60个),我正在尝试读取和处理与这些调用(连接到AMI)相关的CDR事件。
这是我正在使用的库(不是我的,但由于bug而被推到fork)https://github.com/warik/gami
它非常简单,主要操作在gami.go - readDispatcher中。

buf := make([]byte, _READ_BUF)    // read buffer
    for {
        rc, err := (*a.conn).Read(buf)

字符串
因此,有一个TCPConn(a.conn)和大小为1024的缓冲区,我从socket阅读消息。到目前为止一切顺利,但最终,有时(这个时间可能从10分钟到5小时不等,独立于通过套接字的数据量)读取操作失败,并出现io.EOF错误。我试图重新连接并立即重新登录,但它也是不可能的-连接超时,所以我被推到等待约40- 60秒,这段时间对我来说是非常关键的,我失去了很多数据,因为延迟.我在谷歌上搜索,阅读资料,尝试了很多东西-什么都没有。最奇怪的是,在python或php中打开的简单socket不会失败。

  • 有没有可能是因为我的机器或asterisk服务器上缺少表示套接字的文件描述符而导致的问题?
  • 有没有可能是星号配置中的问题(因为我有另一个星号,这个问题不会重现,而且,我在最后一个星号上的调用时间更少)?
  • 在我处理套接字连接或一般的Go语言的方式中,有没有可能存在这个问题?

go版本go1.2.1 linux/amd 64
星号1.8

brccelvz

brccelvz1#

更新至最新星号。当AMI发送大量数据时,会出现这样的错误。
对于检查问题,您可以通过ami命令发送,如“COMMAND sip show peers”(或任何其他长输出命令)并查看结果。

a64a0gku

a64a0gku2#

好的,问题出在操作系统套接字缓冲区溢出。看起来有太多的数据要处理。
所以,有三种可能的方法来解决这个问题:

  • 增加套接字缓冲区容量
  • 提高了从socket读取数据处理速度
  • 较低的数据量或频率

gami默认从asterisk阅读所有数据。我正在阅读所有这些文件,并在实际读取操作后对其进行过滤。根据AMI侦听应用程序运行在相当差的PC上,它似乎根本无法在缓冲区容量暴露之前读取所有数据。但通过向AMI发送“事件”操作并指定所需的“EventMask”,可以仅接收特定事件。所以,我的决定是这样做。并为不同事件类型创建不同的连接。

42fyovps

42fyovps3#

我也遇到了读取数据的问题。我不得不为它做一个单独的线程(go例程),并通过香奈儿发送结果。然后它像 lightning 一样击中了我。read本身阻塞了客户端rutin,因为它等待结束(EOF),但是给定的线程也必须做一些事情,而不仅仅是等待阅读,所以读取必须在单独的线程(例程)中启动,这是一个例子。它通过通道发送阅读结果。

go func(mch chan string, conn net.Conn, ctx context.Context) { 
        reader := bufio.NewReader(conn)
        for {
            s, err := reader.ReadString('#')
            if err != nil {
                mch <- "[read stop] " + fmt.Sprint(err)
                break
            } else {
                mch <- s
            }
            select {
            case <-ctx.Done():
                return
            default:
                za.SleepM(3)
            }
        }
    }(mch, conn, ctx)

字符串

相关问题