在 Go 的 net.Conn 中准确读取数据
在 Go 网络应用领域,问题准确地从网络读取数据。Conn 可能会出现。内置的 Conn.Read 函数虽然方便,但可以将数据读取到用户定义的大小有限的字节数组中。这可能会导致缓冲区分配不足或过多,具体取决于实际数据大小。
为了解决这一困境,可以利用强大的 bufio 包。通过根据需要动态扩展内部缓冲区,bufio 简化了读取未知长度内容的过程。下面是一个修改后的示例:
package main import ( "bufio" "fmt" "io" "net" ) func main() { conn, err := net.Dial("tcp", "google.com:80") if err != nil { fmt.Println("dial error:", err) return } defer conn.Close() fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") // Create a bufio.Scanner to read the response. scanner := bufio.NewScanner(conn) // Iterate over the lines of the response. for scanner.Scan() { line := scanner.Text() fmt.Println(line) } // Check for any errors that occurred during scanning. if err := scanner.Err(); err != nil { fmt.Println("scanner error:", err) } }
此代码使用 net.Conn 作为其源来初始化 bufio.Scanner 对象。扫描程序连续读取数据,直到遇到文件结束 (EOF) 条件或错误。这种方法会在数据流入时自动处理缓冲区扩展,确保准确高效的读取。
或者,对于更直接的方法,您可以使用 io.Copy,如 @fabrizioM 所建议:
func main() { conn, err := net.Dial("tcp", "google.com:80") if err != nil { fmt.Println("dial error:", err) return } defer conn.Close() fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n") // Create a bytes.Buffer to store the response. var buf bytes.Buffer io.Copy(&buf, conn) // Print the total size of the response. fmt.Println("total size:", buf.Len()) }
此示例使用 io.Copy 将 net.Conn 的内容传输到 bytes.Buffer 中,该缓冲区内部管理缓冲区分配和扩展。
以上是如何从 Go net.Conn 准确读取数据?的详细内容。更多信息请关注PHP中文网其他相关文章!