2016-08-24 22 views
0

現在、クライアント/サーバーアプリケーションを作成しており、サーバーからクライアントにファイル(音楽、ビデオ、テキスト、およびその他の種類)を送信する必要があります。クライアントにファイルを送信し、クライアント側のバイナリシリアル化/逆シリアル化を使用してTCP経由でファイルを送信する

let sendFile (client:TcpClient) (srcFilePath:string) = 
    let formatter = new BinaryFormatter() 

    // Deserialize message content to obj 
    use mStream = new MemoryStream() 
    ( 
     use fStream = File.OpenRead srcFilePath 
     fStream.CopyTo mStream 
    ) 
    let deserializedContent = formatter.Deserialize mStream 

    // Create and serialize message into network stream 
    let message = { Type = FileSync; Content = Some deserializedContent } 
    formatter.Serialize (client.GetStream(), message) 

それを受け取るために:

let readStreamToFile (client:TcpClient) outputPath = 
    let formatter = new BinaryFormatter() 

    try 
     let message = (formatter.Deserialize (client.GetStream())) :?> Message 
     match message.Type with 
     | FileSync -> 
      use fileStream = File.Open(outputPath, FileMode.Create) 
      match message.Content with 
      | Some content -> 
       formatter.Serialize (fileStream, message.Content) 
      | None -> 
       failwith "There was no content in the FileSync message!!!" 
     | _ -> 
      () 
    with 
    | :? InvalidCastException as ex -> 
     failwith "Message format unknown!!!" 

formatter.Deserialize mStreamを呼び出すときに、私は次の例外を取得しています現在、私は2つの以下の機能を書きました:

System.Runtime.Serialization.SerializationException:解析が完了する前にストリームの終了が検出されました。

私はMemoryStreamFileStreamをコピーバイパスし、代わりにformatter.Deserialize fStreamを呼び出す場合、私は同じ場所で、次の例外を取得しています:

System.Runtime.Serialization.SerializationException:入力ストリームがあるが有効なバイナリ形式ではありません。 (バイト単位)の開始の内容は以下のとおりです。バイト

はなぜ私のファイルの内容をデシリアライズすることができ、私のBinaryFormatterではないでしょうか?

EDIT:

は、私も次のことを試してみましたが、私のストリームはバイトが含まれていることを確認するために、私は同じThe input stream is not a valid binary format例外を取得しています:

// Deserialize message content to obj 
let fileBytes = File.ReadAllBytes srcFilePath 
use mStream = new MemoryStream() 
mStream.Write (fileBytes, 0, fileBytes.Length) 
mStream.Position <- (int64)0 
let deserializedContent = formatter.Deserialize mStream 
+0

'formatter.Deserialize mStream'の呼び出しは' use'スコープの後に行われるので、その時点で 'mStream'が処分されます。私はなぜあなたが 'ObjectDisposedException'を取得しないのだろうかと思っています... –

+0

これは、私が少し不明であるように書いているかもしれませんが、実際には破棄されている括弧の間にのみ使用されているファイルストリームです。 – Choub890

答えて

1

ソースファイルは、音楽、ビデオの場合は、それらのコンテンツは.NETによってシリアル化されません。したがって、それらを直列化解除することは機能しません。そのため、例外がスローされます。彼らがそうであるようにあなただけのデシリアライズせずに、ファイルをお読みください:

let sendFile (client:TcpClient) (srcFilePath:string) = 
    let formatter = new BinaryFormatter() 

    let fileContent = File.ReadAllBytes srcFilePath 

    // Create and serialize message into network stream 
    let message = { Type = FileSync; Content = Some fileContent } 
    formatter.Serialize (client.GetStream(), message) 
これと一致し

を、あなたは、クライアント側でのファイルの内容をシリアルべきではない:私はタイプを変更した

let readStreamToFile (client:TcpClient) outputPath = 
    let formatter = new BinaryFormatter() 

    try 
     let message = (formatter.Deserialize (client.GetStream())) :?> Message 
     match message.Type with 
     | FileSync -> 
      match message.Content with 
      | Some content -> 
       File.WriteAllBytes(outputPath, content) 
      | None -> 
       failwith "There was no content in the FileSync message!!!" 
     | _ -> 
      () 
    with 
    | :? InvalidCastException as ex -> 
     failwith "Message format unknown!!!" 

注意obj optionからbyte[] optionまでのコンテンツの

関連する問題