我是刚接触lang的新手,无法在go中编写tcp代码。
这些是我的代码
// client
package main
import (
"log"
"net"
"os"
"io"
"fmt"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:4000")
if err != nil {
log.Fatal(err)
}
GetFileFromServer(conn, "test.txt")
}
func GetFileFromServer(conn net.Conn, fileName string) {
file, err := os.Create(fileName)
if err != nil {
log.Fatal(err)
return
}
defer file.Close()
conn.Write([]byte("get:" + fileName))
_, err = io.Copy(file, conn) // **IT DOES NOT STOP!!**
if err != nil {
log.Fatal(err)
return
}
fmt.Println("GET DONE")
}
// server
package main
import (
"bytes"
"log"
"net"
"io"
"fmt"
"strings"
"os"
)
const BUFFER_SIZE = 1024
const DIR_PATH = "./serverFile"
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:4000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := listen.Accept()
if err != nil {
log.Fatal(err)
}
defer conn.Close()
go ConnHandle(conn)
}
}
func ConnHandle(conn net.Conn) {
buffer := make([]byte, BUFFER_SIZE)
_, err := conn.Read(buffer)
if err != nil {
log.Fatal(err)
}
trimedBuffer := bytes.Trim(buffer, "\x00")
command := strings.Split(string(trimedBuffer), ":")
if command[0] == "get" {
PutFileToClient(conn, command[1])
return
}
}
func PutFileToClient(conn net.Conn, fileName string) {
file, err := os.Open(DIR_PATH + "\\" + fileName)
if err != nil {
log.Fatal(err)
return
}
defer file.Close()
_, err = io.Copy(conn, file)
if err != nil {
log.Fatal(err)
return
}
fmt.Println("PUT DONE")
}
- - 我想要的是 - - 我认为“客户端的io.Copy”没有停止的原因是,它一直尝试从连接中读取数据。
如何修复或停止?
最佳答案
正如@BurakSerdar提到的那样,客户端永远不会获得io.EOF
,因为服务器永远不会关闭连接流。
func PutFileToClient(conn net.Conn, fileName string) {
defer conn.Close() // ensures client gets a `io.EOF` on success *OR* failure
// ...
}
但是,您需要注意一些极端情况。尽管可以在服务器端跟踪错误处理,但是从客户端角度来看,它将忽略这些错误并保存以下文件:
io.Copy
失败)为了解决这些情况,建议在连接有效负载的开头写入文件大小的标头,例如
服务器
defer
关闭conn(客户端将获得零字节)b := make([]byte, 8)
binary.LittleEndian.PutUint64(b, fsize)
n, err := io.Copy(conn, b)
客户
fsize := binary.LittleEndian.Uint64(b)
n, err := io.Copy(file, conn)
n == fsize
以确保已接收到完整的有效负载。 关于go - 如何在TCP客户端中停止io.Copy(file,conn)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62842866/