我写的用winsock传输MP3文件的代码,有很多错误,想破脑袋也想不出所以然,望大侠指点。
发送端:
'sckIndex:winsock控件的下标,FPath为要传输的MP3文件文件名(含路径)
Public Function Copy_File(sckIndex As Integer, FPath As String) As Boolean
    Dim Buffer() As Byte
    FLen = FileLen(FPath)
    ReDim Buffer(FLen - 1)'好象是数组越界了?
    Open FPath For Binary As #3
    Get #3, 1, Buffer
    Close #3
    FrmMain.Winsock(sckIndex).SendData (Buffer)
End Function
接收端:
Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)
    Dim Buffer() As Byte
    Dim getLen As Integer
    Winsock.GetData Buffer
    Open "Hello.mp3" For Binary As #1
    Put #1, getLen + 1, Buffer
    Close #1
End Sub

解决方案 »

  1.   

    给你一个参考:转别人的:
    我以前页做过,是手工写的一个文件(0000 1111 2222 ... ffff)然后传送,我发现在发送的时候只要winsock1.senddata filearray()就可以了,但是在接受的那一方的winsock1_dataarrival的事件中一次最多只能收8K,你可以debug一下就可以看到了。所以我的方法是在收的时候加一个计数,直到将整个文件收完再close。你看一下吧。>>> send Private Sub Command1_Click()
    Winsock1.RemoteHost = "127.0.0.1"
    Winsock1.RemotePort = 9988
    Winsock1.Connect
    End SubPrivate Sub Command2_Click()
    Dim FileArray() As Byte
    Open "E:\OICQ\qq.exe" For Binary As #1 '我们测试一个>8K的文件
        'ReDim FileArray(lof(1))    'at first you should tell the client the correct file length
        ReDim FileArray(1720390)    'at first you should tell the client the correct file length
        Get #1, , FileArray
        Winsock1.SendData FileArray
    Close #1
    End Sub
    >>> ReceiveDim FileCount As LongPrivate Sub Form_Load()
    Winsock1.LocalPort = 9988
    Winsock1.Listen
    End SubPrivate Sub Winsock1_Close()
    Winsock1.Close
    Label1.Caption = "Connect Close"
    End SubPrivate Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
    Winsock1.Close
    Winsock1.Accept requestID
    Label1.Caption = "Connect OK"'Open File for write
    Open "e:\oicq\qq2.exe" For Binary As #1
    End SubPrivate Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
    Dim getArray() As Byte
    ReDim getArray(bytesTotal)
    Winsock1.GetData getArrayFileCount = FileCount + bytesTotal
    Label1.Caption = CStr(Int(FileCount * 100 / 1720390)) + " %" '1720390 is the file length. At first you should try to get the correct file length
    If FileCount <= 1720390 + 1 Then
        '1720390 is the file length. At first you should try to get the correct file length
        '1720390+1 是为了文件的实际长度和数组的序号匹配
        Put #1, , getArray
    Else
        Close #1
        Label1.Caption = "Receive OK!"
    End If
    End Sub
      

  2.   

    是不是要分块传输啊?那又要怎么修改呢?我在这里看到了很多这一类的问题,请哪位高手给予关注,给出一个解决方法,相信很多初涉Winsock编程的网友一样关注,请帮忙顶一下,UP有分,谢谢
      

  3.   

    不好意思啊,接收端我是这么写的:getLen应该定义成Static变量吧,如下:
    接收端:
    Private Sub Winsock_DataArrival(ByVal bytesTotal As Long)
        Dim Buffer() As Byte
        Static getLen As Integer
        Winsock.GetData Buffer
        Open "Hello.mp3" For Binary As #1
        Put #1, getLen + 1, Buffer
        Close #1
    End Sub
      

  4.   

    参考一下别人怎么写的吧
    insoft.51.net/soft/filesend.zip
      

  5.   

    开发此类软件需要明白winsock控件发送和接收数据是有限制的,一般小于8K.所以当文件大于8K的时候,应该采取分次发送。我写了个文件服务器和客户端,服务器端同时可以接收几十个客户端同时连接并接受文件,服务器运行非常稳定。经过多次测试,可以正常稳定的传输大型文件,呵呵,我用的测试文件基本上大于500M,若有需要看DEMO (exe) 的,请发送邮件至 [email protected]限前5名 (^_^ 我不可能天天回复嘛)
      

  6.   

    再次说明,需要DEMO(exe)的朋友,请发送邮件至 [email protected]限前5名 (^_^ 我不可能天天回复嘛)
      

  7.   

    这是文件分割函数的代码,参考一下吧Public Function DividePacks(ByVal FileToDivide As String, ByVal PacketSize As Long)
    Dim Position As Long
    Dim TestRetval As Long
    Dim LngSendFileNum As Long, LngFileSize  As Long
    Dim I As Integer
    Dim lngIndex As Long'On Error GoTo ErrorhandlerIf PacketSize = 0 Then PacketSize = 1024
    StrFileName = FileToDivide
        frmServer.lbl.Caption = StrFileName
        LngSendFileNum = FreeFile() '得到空的文件号        Erase StrDataChunk     '重载
            Erase LngPosition       '重载
    '==================================================================
    '取得文件大小,以指定大小拆分成包
    LngFileSize = (FileLen(StrFileName))
    LngPacketSize = PacketSize
    If LngFileSize < LngPacketSize Then
        LngChunkPacks = 1
        ReDim StrDataChunk(LngChunkPacks)
        ReDim LngPosition(LngChunkPacks)
    Else
        LngLastChunkSize = LngFileSize Mod LngPacketSize
        If LngLastChunkSize = 0 Then
                LngChunkPacks = LngFileSize / LngPacketSize
                ReDim StrDataChunk(LngChunkPacks)
                ReDim LngPosition(LngChunkPacks)
        Else
                'StrChunkPacks = LngFileSize / LngPacketSize
                'StrChunkPacks = Left(StrChunkPacks, (InStr(1, StrChunkPacks, ",")) - 1)
                LngChunkPacks = (LngFileSize \ LngPacketSize) + 1
                ReDim StrDataChunk(LngChunkPacks)
                ReDim LngPosition(LngChunkPacks)
       End If
    End If
    '===================================================================
    '拆分过程
    Open StrFileName For Binary As LngSendFileNum
        For lngIndex = 0 To LngChunkPacks - 1
            StrDataChunk(lngIndex) = Input(LngPacketSize, LngSendFileNum)
        Next lngIndex
    Close
    '====================================================================
    '校验包的完整性
    If LngFileSize < LngPacketSize Then
        TestRetval = Len(StrDataChunk(0))
            If TestRetval <> LngFileSize Then
                MsgBox "包校验不完整!"
            Exit Function
            End If
    Else
        For I = 0 To LngChunkPacks - 1
            TestRetval = TestRetval + Len(StrDataChunk(I))
        Next
            If TestRetval <> LngFileSize Then
                MsgBox "包校验不完整!111   =====" & CStr(LngChunkPacks)
            Exit Function
            End If
    End If
    frmServer.lbl.Caption = Str(LngChunkPacks)
    Exit FunctionErrorhandler:
    MsgBox " [1] Error :[" & Err.Number & "] Desc:[" & Err.Description & "]"
    Err.Clear
    Exit FunctionEnd Function现在不在我的计算机上,不然有一份完整的代码给你,不过给你一个思路,在传输过程中一定要有一个校验的协议,比如A发给B一个“SENDFILE”,B返给A“READY”,A收到后分解文件分为若干buffer,告诉B buffer的长度和总数量,B开准备接收,加上一个头,比如"FILEBUFFER-",B接收后去掉头把看看buffer长度是否是指定的大小,再保存到一个二进文件,再发给A一个“SENDNEXT”如果长度不够就发送“SERNDPRE”告诉A重发。。