File 如何在golang中通知TCP客户端文件结束?
我想在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
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连接时,您需要使用网络包中的函数。我认为,即使在之后关闭连接,您仍然需要某种应用程序级协议,以防连接过早关闭。