为什么我的 TCP 套接字读取一段时间后会出现 io.EOF 错误?

问题描述 投票:0回答:3

我在从套接字读取数据时遇到问题。有一个星号实例正在运行大量调用(一分钟 10-60 个),我正在尝试读取和处理与这些调用相关的 CDR 事件(连接到 Amazon 机器实例)。

这是我正在使用的库(不是我的,而是由于错误而分叉的)https://github.com/warik/gami

这非常简单;主要操作在 gami.go - readDispatcher 中。

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

因此,有一个 TCP 连接 (a.conn) 和一个大小为 1024 的缓冲区,我正在从套接字读取消息。到目前为止一切顺利,但最终(该时间可能从 10 分钟到 5 小时不等,与通过套接字传输的数据量无关),读取操作会失败并出现 io.EOF 错误。

我尝试立即重新连接并重新登录,但这不起作用;连接超时,所以我被迫等待大约 40-60 秒才能重新连接。这个时间延迟对我来说非常关键;由于延迟,我丢失了大量数据。在 Python 或 PHP 中打开这样一个简单的套接字不会以同样的方式失败。

可能是什么问题?

问题可能是由于:

  • 我的星号配置(我有另一个星号实例,没有这个问题,但我对最后一个星号实例的调用时间较少)
  • 我的套接字连接实现或一般的 Go 代码

但我不确定。有什么想法吗?

我正在使用 Go 1.2.1 linux/amd64 和 Asterisk 1.8。

sockets tcp go asterisk amazon-ami
3个回答
1
投票

更新到最新的星号。当AMI发送大量数据时出现这样的错误。

对于检查问题,您可以通过 ami 命令发送,例如“COMMAND sip show peers”(或任何其他长输出命令)并查看结果。


-1
投票

好的,问题出在操作系统套接字缓冲区溢出。看来有太多数据需要处理。

因此,有三种可能的方法可以解决此问题:

  • 增加套接字缓冲区容量
  • 以某种方式提高从套接字读取数据的进程速度
  • 较低的数据量或频率

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


-2
投票

我在读取数据时也遇到了问题。我必须为它创建一个单独的线程(goroutine)并通过chanel发送结果。然后它像一道闪电一样击中了我。 读取本身会阻塞客户端 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)
© www.soinside.com 2019 - 2024. All rights reserved.