【发布时间】:2016-11-05 03:14:45
【问题描述】:
我在go 中运行了一个简单的文件传输代码。从服务器端,我尝试一次读取 1024 字节的数据。从客户端我使用io.Copy 函数来传输文件。文件传输在 70% 的时间内成功完成。但是在 30% 的时间里它会失败。它卡在connection.Read 函数上。通过一些实验,我发现只有在之前的Read 操作读取的数据少于1024 字节的数据时才会发生这种情况。
所以从我的代码中,理想情况下,它应该读取所有连续的Read 上的1024 字节数据,除了文件传输完成的最后一个Read。但在某些情况下,如果它读取的字节数少于 1024 字节,则下一个 Read 操作会卡住而不会引发任何错误。这是我的代码:
-
服务器.go
fileBuffer := make([]byte, BUFFER_SIZE) //BUFFER_SIZE is a constant of 1024 bytesRead := int64(0) count := 0 for { if fileSize-bytesRead < int64(BUFFER_SIZE) { //fileSize is the size of file in bytes, which I calculated earlier. fileBuffer = make([]byte, fileSize-bytesRead) } fmt.Println("Reading ", BUFFER_SIZE, " bytes of data") n, err := connection.Read(fileBuffer) count++ fmt.Println("Completed reading", n, " bytes of data, count=", count) file.Write(fileBuffer[0:n]) bytesRead += int64(n) fmt.Println("So far read", bytesRead, " bytes of data") if err != nil { fmt.Println(err) } if err == io.EOF { result.Message = "File transfer incomplete" break } if bytesRead >= fileSize { result.Message = "File transfer complete" break } } -
Client.go
n, err := io.Copy(conn, file) fmt.Println(n, " bytes sent")
就我而言,发送的字节数是正确的,成功传输时接收的字节数也是正确的。问题发生在同一个文件上。
【问题讨论】:
-
您没有在非 EOF 错误上中断,这可能会卡住,并且您没有检查写入计数或错误。为什么不直接使用 io.Copy 或 io.CopyBuffer?
-
是的,我没有打破非 EOF 错误。但如果有任何错误,我会打印。所以在错误的情况下,我希望在控制台上看到一些东西。它只是一个测试应用程序,我不需要它是完美的。我只需要了解为什么文件传输有时会卡住。此外,我正在使用 io.Copy 并打印从客户端发送的字节数,这始终是正确的。
-
您绝对应该在写入文件之前检查错误。如果出现错误(
n不一定定义),永远不要写入文件。
标签: go