如何在golang中通知TCP客户端文件的结尾?

时间:2012-11-01 10:26:06

标签: file networking tcp go

我想在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来通知客户端文件已经结束。

如果我想发送文件,这将无效,我该如何解决?

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:1)

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

,一切正常
defer conn.Close()
打开连接后

例如:

conn, err := net.Dial("tcp", client)
defer conn.Close()

答案 2 :(得分:0)

在正常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