Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用golang诊断从unix套接字读取的速度非常慢(netcat中为1分钟vs 1秒)_Go_Unix Socket - Fatal编程技术网

使用golang诊断从unix套接字读取的速度非常慢(netcat中为1分钟vs 1秒)

使用golang诊断从unix套接字读取的速度非常慢(netcat中为1分钟vs 1秒),go,unix-socket,Go,Unix Socket,背景 Im编写了几个包来与OpenVas漏洞扫描程序进行通信—扫描程序使用了几个不同的缓和协议进行通信—所有这些包都由通过unix套接字或tcp连接发送的xml或文本字符串组成(Im使用unix套接字) 我遇到的问题是OTP协议(OpenVas内部协议,没有很好的文档记录) 我可以使用netcat运行以下命令,并在不到一秒钟的时间内返回响应: echo-en'\n客户端NVT\U信息\n'\ncat-U /var/run/openvassd.sock 这将导致相当大的响应,在终端中如下所示: &

背景 Im编写了几个包来与OpenVas漏洞扫描程序进行通信—扫描程序使用了几个不同的缓和协议进行通信—所有这些包都由通过unix套接字或tcp连接发送的xml或文本字符串组成(Im使用unix套接字)

我遇到的问题是OTP协议(OpenVas内部协议,没有很好的文档记录)

我可以使用netcat运行以下命令,并在不到一秒钟的时间内返回响应:

echo-en'\n客户端NVT\U信息\n'\ncat-U /var/run/openvassd.sock

这将导致相当大的响应,在终端中如下所示:

< OTP/2.0 >
SERVER <|> NVT_INFO <|> 201802131248 <|> SERVER
SERVER <|> PREFERENCES <|>
cache_folder <|> /var/cache/openvas
include_folders <|> /var/lib/openvas/plugins
max_hosts <|> 30
//lots more here
我得到了完整的结果,但它是以小块的形式出现的(我猜是一行一行),所以我看到的输出是这样的(在显示完整响应之前的一分钟左右):

所以我决定尝试ioutil.ReadAll:

func (c Client) read() ([]byte, error) {
    fmt.Println("read start")
    d, err := ioutil.ReadAll(c.conn)
    fmt.Println("read done")
    return d, err
}
这确实会再次返回完整响应,但“读取开始”和“读取完成”之间的时间约为一分钟,而该命令预计将花费<1秒的时间


与netcat相比,golang的读取速度为何如此之慢?我如何诊断/修复该问题?***

该服务似乎正在等待更多输入,并最终在一分钟后超时。在您的CLI示例中,一旦
echo
命令完成,管道的这一侧将关闭以进行写入,在这种情况下,服务将收到0长度recv的通知

为了在Go中执行同样的操作,您需要在完成发送命令后调用
net.UnixConn

c.conn.(*net.UnixConn).CloseWrite()

我不明白这个问题,但可能是因为你没有正确地阅读插座在第一位。
Read
调用永远不能保证返回字节的缓冲区大小,它返回可用的内容。再次阅读文档。在检查错误之前,必须先检查读取的字节数。读取的字节数小于缓冲区大小并不表示任何情况。根据更新的问题,我已删除了返回的位,如果响应小于缓冲区大小,我现在将以点滴的形式返回完整响应。悬而未决的问题是,当netcat在不到一秒钟的时间内将其收回时,返回完整响应(通过read或ReadAll)所需的时间为何如此之长@Kostix,没有文档(最新的),所以查看源代码是我能找到的唯一方法,但我不认为我看到的问题与openvas或协议有关,因为netcat在没有任何知识的情况下处理得很好。@JimB感谢您的建议(在前面的评论中错过了)-这似乎对响应时间没有任何影响,我已经改变了,因为我猜在阅读错误时有可能丢失消息的一部分。我在go中的两次尝试都需要一分钟,通过netcat需要一秒钟的时间——这就是为什么go和netcat之间存在~59秒的差异的问题——我希望类似的情况performance@WebweaverD,
c.conn.(*net.UnixConn).CloseWrite()
应该涵盖您。原因是您似乎使用了通用连接函数
net.Dial
,它返回一个接口值
net.Conn
(因为它是通用的)。您可以使用
net.dialnix
获取具体类型的值,
net.UnixConn
返回。不过,当您将“unix”作为第一个参数传递给
net.Dial
,您将得到
net.UnixConn
的一个实例,因此在POSIX系统上键入assert it.JFTR,
CloseWrite()
calls是安全的;希望这能向OP更多地解释这种行为。
func (c Client) read() ([]byte, error) {
    fmt.Println("read start")
    d, err := ioutil.ReadAll(c.conn)
    fmt.Println("read done")
    return d, err
}
c.conn.(*net.UnixConn).CloseWrite()