如何用vb的winsocket解决udp文件传送丢包的问题

udp协议是1种无连接的协议,他和tcp协议比较有传输速度快,占用资源少的问题。
但是由于udp协议本身没有自动找包的功能,因此经常会出现丢包的现象,会造成传送的文件丢包的现象
因为时间匆忙和水平有限,本人在效率上没有作优化,只是简单的实现,请大家自己看源码吧
注释:
主要功能:把文件猜成4k大小的包 在包头+上包的长度 接受了1个包判断长度是否和接受的长度相符如果

符合那么就继续发,如果出现丢包那么就从发
希望大家有什么好的建议通知我,我会尽量完善的

Option   Explicit
' ==============================================
'
===============================
'
udp传文件
'
客户端
'
作者: 影子
'
================================
'
==============================================
Dim  FileNumber  As   Integer   ' 用来存文件的句柄
Dim  LenFile  As   Long   ' 文件的长度
Private   Sub  Command2_Click()
    closefile
End Sub

Private   Sub  Form_Load()
    Winsock0.LocalPort 
=   5698
    Winsock0.Bind
    beginfile
End Sub
Private   Sub  Winsock0_DataArrival(ByVal bytesTotal  As   Long )
    
Dim  FileByte()  As   Byte
    Winsock0.GetData FileByte, vbArray 
+  vbByte  ' 接收类型为:字节数组
     Dim  mendByte()  As   Byte , i  As   Long , j  As   Long
    
Dim  temp  As   String , temp1  As   String
    
' 获得包长
    j  =   UBound (FileByte)
    
' 合并包头
     For  i  =   0   To   7  Step  2
        temp 
=  temp  &   Chr $(FileByte(i))
    
Next
    
' 比较长度看丢包没有
     If  Val(temp)  =  j  Then

        
ReDim  mendByte(j  -   8 )
        
'     提出包头
         For  i  =   0   To  j  -   8
            mendByte(i) 
=  FileByte(i  +   7 )
        
Next
        
'         写文件
        Put #FileNumber, , mendByte
        
'     发送继续发送的请求
        frmmain.Winsock0.SendData  " ok "
    
Else
        
' 出现丢包,请求重发
        frmmain.Winsock0.SendData  " no "
    
End   If
End Sub

Public   Sub  beginfile()
    FileNumber 
=  FreeFile  ' 取得未使用的文件号
    Open  " c:\aaa.exe "   For  Binary  As  #FileNumber  ' 打开文件
End Sub

Public   Sub  closefile()  ' 关闭文件句柄
    Close #FileNumber
End Sub

Option   Explicit
Dim  GetFileNum  As   Integer
Dim  LenFile  As   Long
Dim  Sendbaye()  As   Byte   ' 发送的包
'
===============================
'
udp传文件
'
作者: 影子
'
服务器端
'
================================

Private   Sub  Command1_Click()
    GetFileNum 
=  FreeFile  ' 取得未使用的文件号
    LenFile  =  FileLen( " d:\aa.rar " ' 获得需传送的文件的长度
    Open  " d:\aa.rar "   For  Binary  As  #GetFileNum  ' 打开需传送的文件
    Command1.Enabled  =   False
    
'         传送文件
     Call  TCPSendFile(frmmain.Winsock0, GetFileNum, SplitFile)
    Text1.Text 
=   Now
End Sub

Private   Sub  Form_Load()
    frmmain.Winsock0.RemoteHost 
=   " 192.168.0.12 "   ' 服务器ip
    frmmain.Winsock0.RemotePort  =   5698

End Sub
' =========================================================================
'
为了清晰,下面分别用两个子过程来完成计算这次还可以传多少个字节的数据和传送数据
'
==========================================================================
Private   Function  SplitFile()  As   Long   ' 拆包
     On   Error   Resume   Next
    
Dim  GetCount  As   Long
    
' 计算出这次可发送的字节数
     If  LenFile  >=   4000   Then
        GetCount 
=   4000
        LenFile 
=  LenFile  -  GetCount
    
Else
        GetCount 
=  LenFile
        LenFile 
=  LenFile  -  GetCount
    
End   If
    SplitFile 
=  GetCount

End Function
Private   Sub  TCPSendFile(objWinSock  As  Winsock, FileNumber  As   Integer , SendLen  As   Long )
    
Dim  FileByte()  As   Byte , i  As   Long , j  As   Long
    
Dim  temp  As   String
    
ReDim  Sendbaye( 0 )

    
Dim  tempa  As   String   *   4
    
ReDim  FileByte(SendLen  -   1 )
    tempa 
=  SendLen  +   7
    Sendbaye 
=  tempa  '  把长度负值给包头
     Get  #FileNumber, , FileByte  ' 读取文件
     ReDim  Preserve Sendbaye(SendLen  +   7 ' 把包头+到文件头
     For  i  =   0   To   UBound (FileByte)
        Sendbaye(i 
+   7 =  FileByte(i)
    
Next
    frmmain.Winsock0.SendData Sendbaye
End Sub

Private   Sub  Winsock0_DataArrival(ByVal bytesTotal  As   Long )
    
Dim  str  As   String
    frmmain.Winsock0.GetData str
    
Select   Case  str
    
Case   " ok "
        
' 成功继续发送
         If  LenFile  =   0   Then   ' 发送完成
             MsgBox   " 成功 "
            
Exit   Sub
        
End   If
        
Call  TCPSendFile(frmmain.Winsock0, GetFileNum, SplitFile)
    
Case   " no "
        
' 不成功重发上一个包
        frmmain.Winsock0.SendData Sendbaye
    
End   Select
End Sub

sdfsdfsf

 

你可能感兴趣的:(socket)