2013-02-04 38 views
0

我在VB.Net中創建了文件共享程序,但是當我嘗試發送文件時,接收部分沒有正確接收文件。只有我發送的文件的一部分。比方說,我發了一個100MB的文件,只收到10MB。有時候有22 KB,39 MB等等。接收文件的大小並不總是相同的。你認爲什麼導致這個問題?我該如何正確接收整個文件?VB.Net文件傳輸:收到的文件不完整

發送部分

Sub Main() 
    Dim ip As New IPEndPoint(IPAddress.Any, 8888)' Port Server 
    Dim sock As New Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)' Protocol type 
    sock.Bind(ip) 
    sock.Listen(100) 
    While True' Check Client Connection 
     Try 
      msg("Accept Client Connect") 
      Dim csock As Sockets.Socket = sock.Accept 
      Dim csend(1024 * 10000) As Byte 
      Dim path As String = "C:\Users\IT\Desktop\test\" ' Location to save file 
      Dim bLen As Integer = csock.Receive(csend) ' Byte Read Len 
      Dim fileLen As Integer = BitConverter.ToInt32(csend, 0) ' File Len 
      Dim fName As String = Encoding.ASCII.GetString(csend, 4, fileLen) ' File Name 
      msg("Start Receive....." & fName) 
      Dim bWrite As New BinaryWriter(File.Open(path + fName, FileMode.Append)) 
      bWrite.Write(csend, 4 + fileLen, bLen - 4 - fileLen) 
      msg("File receiced and Save " & path) 
      bWrite.Close() 
      csock.Close() 
     Catch ex As Exception 
      msg(ex.Message) 
     End Try 
    End While 
    Console.ReadLine() 
End Sub 

Sub msg(ByVal mesg As String) 
mesg.Trim() 
Console.WriteLine(" >> " + mesg) 
End Sub 

接收部分

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)  Handles Button2.Click 
    Dim ipServer As IPAddress() = Dns.GetHostAddresses("127.0.0.1") ' IP Server 
    Dim ip As IPEndPoint = New IPEndPoint(ipServer(0), 8888) 
    Dim csock As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream,  ProtocolType.IP) 
    Dim fName As String = TextBox1.Text 
    Dim path As String = TextBox2.Text 
    Dim fNameByte() As Byte = Encoding.ASCII.GetBytes(fName) 
    Dim fData() As Byte = File.ReadAllBytes(path & "\" & fName) 
    Dim cData(4 + fName.Length + fData.Length) As Byte 
    Dim fDataLen() As Byte = BitConverter.GetBytes(fNameByte.Length) 
    Try 
     fDataLen.CopyTo(cData, 0) 
     fNameByte.CopyTo(cData, 4) 
     fData.CopyTo(cData, 4 + fNameByte.Length) 
     csock.Connect(ip) 
     csock.Send(cData) 
     MsgBox("Success Send File ") 
     csock.Close() 
    Catch ex As Exception 
     MsgBox(ex.Message) 
    End Try 
End Sub 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then 
    TextBox1.Text = System.IO.Path.GetFileName(OpenFileDialog1.FileName) 
    TextBox2.Text = System.IO.Path.GetDirectoryName(OpenFileDialog1.FileName) 
    End If 
End Sub 
+1

你希望你只用一個Receive()調用就能得到整個文件。這是行不通的,你必須繼續調用Receive(),直到你收到所有的字節。 –

+0

好的。感謝那。所以,這意味着我需要通過塊來獲取字節。還有一個問題,我可以通過網絡發送字節塊的最大大小是多少? –

+0

沒有塊,TCP是*流*。每次Receive()調用都會得到不可預知的字節數。發送它比較容易,Send()調用將被阻塞直到可以發送字節。您通常使用一個循環,從文件和Send()中一次讀取4096個字節。當文件很大時,使用少量內存並防止程序崩潰是一種好方法。 –

回答

0

錯誤1,一個創建了追加模式,這應該是二進制文件線07

錯2,嵌套循環創建
應該已被用於接收分組。這裏我添加do〜循環。一個如果條件檢查天氣另一分組是可用或不可用支票它的大小,如果大小= 0,則在線08〜13

錯誤3,接收到所述第一包時退出循環,它被寫入文件減去元數據。像bWrite.Write(csend,4 + fileLen,bLen-4-fileLen)。 at 06/10對於第一個數據包來說這樣很好,但對於其餘數據包卻沒有。因爲元數據在開始時只發送一次,所以它不應該從每個數據包中刪除。剩餘的值應該是0,在這種情況下,包的長度是bLen。正如你可以在行12我看到重置這些值。

  01, Dim csock As Sockets.Socket = sock.Accept 
     02, Dim csend(1024 * 10000) As Byte 
     03, Dim bLen As Integer = csock.Receive(csend) ' Byte Read Len 
     04, Dim fileLen As Integer = BitConverter.ToInt32(csend, 0) ' File Len 
     05, Dim fName As String = Encoding.ASCII.GetString(csend, 4, fileLen) ' File Name 
     06, Dim strt As Integer = 4 + fileLen, ln As Integer = bLen - 4 - fileLen 

     07, Dim bWrite As New BinaryWriter(File.Open(path + fName, FileMode.Create)) 
     08, Do 
     09,  If bLen = 0 Then Exit Do 
     10,  bWrite.Write(csend, strt, ln) 
     11,  bLen = csock.Receive(csend) ' Byte Read Len 
     12,  strt = 0 : ln = bLen 
     13, Loop 

對不起,我試着盡我所能解釋它。