2017-11-28 28 views
1

내 목표는 NetworkStream을 사용하여 TCP 연결을 통해 파일을 보내는 것입니다. 먼저 보낼 데이터의 길이를 보낸 다음 파일 스트림과 이진 작성기를 사용하여 바이트 단위로 데이터를 보냅니다.NetworkStream을 통해 보낸 파일이 손상되었습니다. C#

프로세스를 디버깅하는 동안 수신 측에서 파일의 시작 위치에 '0'바이트가 삽입되어있는 것으로 나타났습니다. 예를 들어 기본 파일의 내용 azertyuiopazerty (4 공백은 uiop을 대체)으로 수신되어 이미지와 같은 파일이 손상됩니다.

내가 지금까지 가지고 코드 : (BR은 BinaryReader를하고 BW는 BinaryWriter 인 경우)

보낸 사람 :

using (var readStream = new FileStream(fileLocation, FileMode.Open)) 
{ 
    // Send the data length first 
    bw.Write(new FileInfo(fileLocation).Length); 
    bw.Flush(); 

    var buffer = new byte[1]; 
    while (readStream.Read(buffer, 0, 1) > 0) 
    { 
      bw.Write(buffer[0]); 
      bw.Flush(); 
    } 
} 

수신기 :

// Get data length 
var dataLength = br.ReadInt32(); 

using (var fs = new FileStream(newFileLocation, FileMode.Create)) 
{ 
    var buffer = new byte[1]; 
    for(int i = 0; i < dataLength; i++) 
    { 
     br.Read(buffer, 0, 1); 
     fs.Write(buffer, 0, 1); 
    } 
} 

무엇 오전 누락되었거나 잘못하고 있습니까?

bw.Write(new FileInfo(fileLocation).Length); 
... 
var dataLength = br.ReadInt32(); 

Length 속성이 실제로 유형 long (8 바이트)입니다 :

+0

데이터의 길이를 보내고받는 방법을 보려면이 응답 (https://stackoverflow.com/questions/7099875/sending-messages-and-files-over-networkstream)을보십시오. –

+1

문제는 아니지만 한 번에 한 바이트 씩 읽고 쓰는 것은 매우 비효율적입니다. 더 큰 버퍼와 Read 호출 결과를 사용하여 작성해야하는 내용을 확인하십시오. –

+0

특히 모든 바이트를 버려 두지 마십시오. – pm100

답변

2

이 문제는 다음이 될 수없는 긴입니다. 그러나 값을 Int32 (4 바이트)로 읽으므로 다른 4 바이트는 스트림에 남겨 둡니다.

+0

고맙습니다. 질문이 하나 더 있습니다. 크기 1의 바이트 배열을 사용하는 것보다 낫습니다. 더 많은 크기일까요? – Valsov

+0

예, 버퍼 크기를 몇 킬로 바이트로 늘려 루프를 적절하게 조정해야합니다. 스트림을 읽을 때는 실제로 읽은 바이트 수를 반환하므로 Read() 메서드의 반환 값에주의하십시오. 이렇게하면 버퍼가 읽은 마지막 부분보다 더 큰 경우에도 스트림의 끝에 도달했을 때를 결정하는 데 도움이됩니다. 그렇게하면 데이터 길이 값을 모두 사용하는 것을 피할 수 있으며 대신 스트림의 끝을 확인하십시오. – uncoder

1

fileinfo.length는 INT32