我做一个局域网内传输文件的小程序,用的是winsock控件,用msgbox进行测试,每一步均能执行,但是如果发送8KB以内的文件就可以,发送8KB以上的文件就会报错:运行时错误“52”,错误的文件名或数。并且更奇怪的是,只有加上那些测试用的msgbox才会出错,如果注释掉它们,程序就一点反应都没有。下面是发送端的代码:
本人已经被这个问题困扰4天了,在线等待答案,有能解答的高分立马送上!!感激不尽!!' 保存的是文件访问句柄,必需是全局的
Dim fl As IntegerPrivate Sub sendfile()
    Dim srcPath As String       'srcPath为要传送的文件所在路径
    Dim strBuffer As String     'str用来记录每一块的内容
    Dim filelength As Long      '为文件的长度
    Dim blocks As Long          '文件分为的块数
    Dim remain As Long          '剩余文件的大小
    Dim i As Long               '中间变量
    
    srcPath = "D:\4.doc"
    filelength = FileLen(srcPath)
    blocks = Fix(filelength / 8100)
    remain = filelength Mod 8100
    
    Winsock1.SendData "Start"           ' 告诉接收端做好接收文件前的准备工作
    MsgBox 1
    Open srcPath For Binary As #1
    If blocks > 0 Then
        For i = 1 To blocks
            strBuffer = Space(8100)  ' space 同 string(8192, " "), 即产生n个空格
            Get #1, , strBuffer
            strBuffer = "DATA" & strBuffer
            Winsock1.SendData strBuffer ' 分块发送文件
           MsgBox 2
        Next
    End If
    
    If remain > 0 Then
        strBuffer = Space(remain)
        Get #1, , strBuffer
        strBuffer = "DATA" & strBuffer
        Winsock1.SendData strBuffer
        MsgBox 3
    End If
    
    Close #1
   MsgBox 4
    Winsock1.SendData "over"            ' 告诉接收端做好文件接收完毕后的收尾工作
    MsgBox 5
    
End Sub
Private Sub sendCMD_Click()
    Call sendfile
End SubPrivate Sub Form_Load()  'winsock1用于发送,winsock2用于监听
    Winsock1.RemoteHost = "192.168.1.22"
    Winsock1.RemotePort = 1300
    Winsock1.Connect
    'Winsock2.LocalPort = 1300
    'Winsock2.Listen
End SubPrivate Sub Winsock1_Connect()
MsgBox 6
End Sub
下面是接收端的代码:
' 保存的是文件访问句柄,必需是全局的
Dim fl As Integer
Dim dstPath As StringPrivate Sub Form_Load()  'winsock1用于发送,winsock2用于监听
    Winsock2.LocalPort = 1300
    Winsock2.Listen
End SubPrivate Sub Winsock2_ConnectionRequest(ByVal requestID As Long)
    If Winsock2.State <> sckClosed Then Winsock2.Close
    Winsock2.Accept requestID
End SubPrivate Sub Winsock2_DataArrival(ByVal bytesTotal As Long)    Dim str2 As String   '用来记录收到的块的内容
  
    dstPath = "D:\4.doc"
    
    Winsock2.GetData str2    If str2 = "Start" Then                  ' 收到开始指令,创建文件        If Dir("D:\4.doc") <> "" Then       ' 创建文件前如果文件存在,则将之删除            Kill ("D:\4.doc")
        End If        fl = FreeFile
        Open dstPath For Binary As #fl
    MsgBox 1
        
    ElseIf str2 = "over" Then               ' 收到结束指令,关闭文件        Close #fl
        Winsock2.Close
        Winsock2.Listen
   MsgBox 2
    ElseIf Left(str2, 4) = "DATA" Then
       MsgBox 3
        Put #fl, , str2                     ' 收到的一定是文件数据包,将他写入文件
      MsgBox 4
    End If
    
End Sub

解决方案 »

  1.   

    If blocks > 0 Then
            For i = 1 To blocks
                strBuffer = Space(8100)  ' space 同 string(8192, " "), 即产生n个空格
                '''''''''''''''''''''Get #1, , strBuffer
                Get #1, , strBuffer, (i - 1) * 8100 + 1
                strBuffer = "DATA" & strBuffer
                Winsock1.SendData strBuffer ' 分块发送文件
               MsgBox 2
            Next
        End If
        
        If remain > 0 Then
            strBuffer = Space(remain)
            '''''''''''''''''''''Get #1, , strBuffer
            Get #1, , strBuffer, blocks * 8100 + 1
            strBuffer = "DATA" & strBuffer
            Winsock1.SendData strBuffer
            MsgBox 3
        End If
      

  2.   

    SendData 需要等得,如下:
    private m_SendComplete as booleanprivate sub Winsock1_SendComplete()
      m_sendcomplete = true
    end ifm_sendcomplete = false
    winsock1.SendData strbuffer
    while not m_sendcomplete
      doevents
    wend
      

  3.   

    收发文件最好不要用 DataArrival 事件,结构太散。用winsock的 senddata 后最好加上 doevents ,否则多次发送的内容可能会被整合成一次发送,
    所以你在发送 start 和 over 时可能会与文件的内容整合一次性发送出去,导致接收端发生错误。
      

  4.   

    不要用String作为文件数据的载体类型,用byte数组
    本来我又文件传送的代码的~可惜现在在家,发不了给你
      

  5.   

    Tiger_Zhao(VB老鸟) 观点值得一试。
    看了你的发送代码,还没发现有问题,每次发送8k,数据量不小,需要检查发送完毕后,再接着下一次发送。