3

我想在 golang 中通过 TCP 发送文件。这是我的服务器代码:

    c is connected *net.TCPConn

    file, _ := os.Open(fn)
    defer file.Close()
    io.Copy(c, file)
    // c.CloseWrite()

和客户:

    as above, c is connected *net.TCPConn

    file, _ := os.Create("file.txt")
    defer file.Close()
    io.Copy(file, c)

我的问题是:这样,客户端无法接收到文件的EOF

所以,io.Copy被屏蔽了。我必须打电话c.CloseWrite通知客户文件已经结束。

如果我想发送文件,这将不起作用,我该如何解决这个问题?

4

3 回答 3

5

如果你使用的是 TCP 连接,那么 os.EOF 错误意味着连接被另一端关闭。

我认为可靠发送文件的唯一方法是实现多状态协议。

例如。在传输的第一个状态,告诉客户端要读取多少字节并进入状态 2。在状态 2,如果读取了所有字节,那么我们知道它读取了整个文件。如果在读取所有字节之前检测到 os.EOF,则丢弃并重新开始。

于 2012-11-01T10:54:01.353 回答
2

在正常的 C 中,一个人会关闭(fd,SHUT_WR)TCP 连接以向另一端指示 EOF。你也可以这样做:

func shutdownWrite(conn net.Conn) {
     // anonymous interface. Could explicitly use TCP instead.
     if  v, ok := conn.(interface{ CloseWrite() error }); ok {
         v.CloseWrite()
     }
 }

https://golang.org/src/net/tcpsock_posix.go?s=2073:2109#L75

于 2016-08-01T16:59:36.583 回答
1

如果您从发送方关闭连接,一切正常。
我现在做了同样的事情——通过 TCP 传输文件。如果您添加,一切正常

defer conn.Close()

打开连接后。
例如:

conn, err := net.Dial("tcp", client)
defer conn.Close()
于 2017-01-04T23:34:01.893 回答