Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File 如何在golang中通知TCP客户端文件结束?_File_Networking_Tcp_Go - Fatal编程技术网

File 如何在golang中通知TCP客户端文件结束?

File 如何在golang中通知TCP客户端文件结束?,file,networking,tcp,go,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") de

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


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

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

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


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

在正常C中,一方将关闭(fd,SHUT_WR)TCP连接,以向另一方指示EOF。您也可以在go中执行此操作:

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

请参见

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

defer conn.Close()
打开连接后。
例如:

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

所以我必须使用c.Read,io.Copy在这里是无用的?@dilfish,Allent想问你的是:你的意思是你想向客户端发送一个文件,但不想在此之后终止TCP连接?如果是,那么这就不起作用了,因为TCP只是传输不透明的字节流,而解释它是客户端的任务。因此,您必须在TCP之上设计一个“应用程序级协议”。正如Allen所建议的,服务器可能首先指示它将发送多少字节,然后客户端读取这些字节,将它们写入文件并等待其他“传输指示符”或其他任何东西。谢谢,我的问题是,io.Copy是否不适合这种情况?这似乎是不正确的。正确的,在使用TCP连接时,您需要使用网络包中的函数。我认为,即使在之后关闭连接,您仍然需要某种应用程序级协议,以防连接过早关闭。