当前位置: 首页 > 面试题库 >

去TCP读取是非阻塞的

邹桐
2023-03-14
问题内容

我正在尝试在Go中创建服务器和客户端,我已经设法与服务器和客户端进行通信。但是我的问题是,在golang中读取的TCP是非阻塞的。我想知道的是,golang中的读取是否有可能像C中的读取一样被阻塞。谢谢

编辑:

这是服务器的源代码:

func Init_tcp() *net.TCPListener {
    laddr, err := net.ResolveTCPAddr("tcp", ":4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.ListenTCP("tcp", laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
    tcp := Init_tcp()
    conn, _ := tcp.Accept()
    data := make([]byte, 512)
    conn.SetNoDelay(false)
    for {
            conn.Read(data)
            fmt.Println(data)
    }
}

和我的客户:

func Init_tcp() *net.TCPConn {
    laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.DialTCP("tcp", nil, laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
   tcp := Init_tcp()
   tcp.Write([]byte("hello world"))
}

问题答案:

Reader可以返回部分数据。从该文档,“如果某些数据是可用的,但不是LEN(P)个字节,读取常规返回什么是可用的,而不是等待更多。”

无论使用哪种语言,这都是一个问题,即使在C语言中碰巧对您有用:TCP只是提供了可以随时写入的字节流。从设计上讲,单次写入可能会分解为多个数据包进行传输,并且没有向接收方发送的内置信号说明单次写入/消息/请求在何处结束。该应用程序必须找出自己的信号边界方法。这可能意味着定界符(\n)或隐式或显式的字节计数(HTTP
Content-Length是显式的)。

要读取特定数量的输入字节,您需要io.ReadAtLeastio.ReadFull。要读取直到满足某些任意条件Read,只要没有错误,就应该在调用上循环。(然后,您可能想对太大的输入进行错误处理,以防止不良的客户端占用服务器资源。)如果要实现基于文本的协议,则应考虑使用net/textproto,它会将a
bufio.Reader放在连接的前面,以便您可以读行。要限制您等待多长时间才能完成读取(以使行为不正常的客户端无法永远挂断goroutine并永远使用内存等),请查看名称中的net函数Deadline(与上的Timeout函数相关)Error类型)。的context
软件包可帮助管理超时,期限和取消,并且在例如要编写一台复杂的服务器来对每个请求执行许多网络操作的情况下特别有用。

该示例代码可能存在不相关但很重要的问题:它丢弃了Readand中的错误Write。这可能掩盖了简单的问题,并使它们很难调试。如果考虑了部分读取后仍遇到问题,请先检查所有错误,然后再寻求更多帮助。查看errcheck以确保不会将此类错误付诸实践。



 类似资料:
  • 问题内容: 我有这段代码可以在Linux中从Serial读取,但是我不知道在读取SerialPort时阻塞和非阻塞之间有什么区别,在哪种情况下哪个更好? 问题答案: 您提到的代码是IMO编码和注释不当的代码。该代码不符合POSIX的可移植性惯例,如正确设置终端模式和POSIX操作系统的串行编程指南中所述。该代码没有提到它使用非规范(也称为原始)模式,并且重用了“阻塞”和“非阻塞”术语来描述 VMI

  • 问题内容: Java中是否有非阻塞文件读取API?如果不是,在C ++中构建一个并通过JNI从Java应用程序中调用它是否明智? 问题答案: 不,不扩展。 可能是因为并非所有的操作系​​统都支持它。 Windows确实如此,从理论上讲,您可以编写Windows特定的C ++库,并通过JNI进行调用,但是将其与集成是很多工作。 我宁愿有一个工作线程将文件内容复制到管道中,并在管道的另一端进行非阻塞读

  • 问题内容: 我需要使用逐行读取文件,但是没有像一次读取一个完整行的方法。有什么解决方案? 问题答案: NIO通常用于直接内存访问或块介导的批量数据传输。它可以做其他事情,但是其他功能与阻塞和非阻塞数据访问有更多关系。 因此,您可能想使用NIO来快速(或以非阻塞方式)获取数据。但是,如果要“逐行读取”,最好在NIO读取可用数据后进行行检测。可以通过在NIO刚刚读取的缓冲区上放置“行读取”外观来轻松实

  • 我有一个顶点,它有一个处理程序,可以在事件循环线程中调用Vertx的Web客户端。实际的底层API调用是同步的还是异步的?它会阻塞我的事件循环线程吗?假设我的API调用需要30秒才能返回。 我是否需要用Vertx.execute阻塞(p-

  • 非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser

  • Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S