2016-09-26 108 views
0

的godocs说:当我得到的是一个net.TCPConn的EOF,我怎么知道连接是否已经被丢弃?

“EOF是通过读取返回的错误,当没有更多的输入可用函数应返回EOF只有信号输入的优美端如果在一个结构化的数据流意外发生EOF的。适当的错误是ErrUnexpectedEOF或一些其他错误给出更多的细节。“

和在我的程序中我会love爱得到ErrUnexpectedEOF,但我没有。即使客户端在发送文件的过程中终止,我也总是得到EOF。

所以,我卡住了。通过发送EOF结束的方式传输100%的成功文件。并且通过错误退出50%的文件也会发送EOF作为错误。我不知道传输前文件的总大小。

有没有更多的信息可以从网上获得.TCPConn知道这是一个完整的文件还是不是?

+3

这是TCP的工作原理。您需要一些更高级别的协议来确定连接是否提前关闭。 – JimB

+0

@JimB是对的。 TCP是一种“流式”协议,可以流式传输字节,而不是基于数据包/数据块的协议。 –

+0

那么,Go怎么知道EOF是意外的? – immibis

回答

1

TCP是一种流媒体协议;一串字节。这就是文件传输协议在TCP上发明/实现的原因,如FTP(文件传输协议)。

但是(不推荐/思想实验)如果你可以发送不包含特定字符/字节的块(如base64 + \ n作为那个特定字符),那么你可以使用该特定字符作为分隔符。

现在,如果我们使用类似这样的功能处理我们之间的联系:

func (srv *Server) handler(conn net.Conn) { 
    //... 

    defer srv.closeConnection(conn, nil) 

    reader := bufio.NewReader(conn) 
    writer := bufio.NewWriter(conn) 

    //... 

    conn.SetDeadline(time.Now().Add(conf.ClientTimeout)) 

    for { 
     select { 
     case <-conf.QuitSignal: 
      return 
     default: 
      line, err := reader.ReadBytes('\n') 
      if err != nil { 
       return 
      } 

      //... 
     } 

     conn.SetDeadline(time.Now().Add(conf.ClientTimeout)) 
    } 
} 

func (srv *Server) closeConnection(conn net.Conn, err error) { 
    conn.Close() 
    //... 
} 

Reader.ReadBytes文件,我们读到的ReadBytes回报犯错=零当且仅当返回的数据并没有结束!在分隔符。这样我们就可以识别出碎块。

相关问题