2016-09-26 3 views
0

g120と言う:私が得るのはnet.TCPConnからのEOFです。接続が切断されたかどうかはどのように分かりますか?

"EOFは入力が利用できなくなったときに返されるエラーです。関数は、入力が正常終了したことを知らせるためにEOFを返す必要があります。適切なエラーは、ErrUnexpectedEOFまたは詳細を示す他のエラーのいずれかです。

私のプログラムでは、loveがErrUnexpectedEOFを愛するが、私はそうではない。クライアントがファイルを送信している途中で終了しても、私はいつもEOFを取得します。

だから、私は立ち往生しています。終了時にEOFを送信する方法の100%を転送する成功したファイル。また、エラーを伴って50%を終了するファイルも、EOFをエラーとして送信します。私は転送の前にファイルの合計サイズを知りません。

net.TCPConnから取得できる情報は、これがフルファイルかどうかを知ることはできますか?

+3

これはTCPの動作方法です。接続が早期に終了したかどうかを判断するには、より高いレベルのプロトコルが必要です。 – JimB

+0

@JimBが正しいです。 TCPは、パケット/ブロックベースのプロトコルではなく、バイトをストリームする「ストリーミング」プロトコルです。 –

+0

Goは、EOFが予期せぬことをどのように知っていますか? – immibis

答えて

1

TCPはストリーミングプロトコルです。バイトのストリームそのため、FTP(ファイル転送プロトコル)のように、TCP上でファイル転送プロトコルが発明/実装されました。

特定の文字/バイト(特定の文字としてbase64 + \ nなど)が含まれていない塊でファイルを送信できる場合は、その特定の文字を区切り文字として使用できます。今、私たちはこれと同様の機能を使用して、当社の接続を処理する場合

:!Reader.ReadBytesのドキュメントから

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() 
    //... 
} 

は、我々は唯一の場合返されたデータが終わらない場合ReadBytes戻り、nilを=誤る読みますデリミタで。このようにして、壊れたチャンクを認識することができます。

関連する問題