vbwinsock控件:VB中使用WinSock控件传送文件



    传送文件对于网络编程来说是基本功能比如远程控制软件Software在编制个软件Software时我从网上下了很多传文件这些提供传文件功能根本就不能用传文本还可以传 2进制文件根本就不行因此作为个基本功能模块有必要单独介绍
    首先在VB中要传送你可以这样写:
Dim strData As String
strData = \"Test\"
Winsock1.SendData strData
    但是如果你传送 2进制文件你还能用String变量来存放吗?从理论上分析是不行我也做了实验确实是不行文件虽然可以传但是接受文件和发送原因可能是 2进制文件里可以有任何\"\"但是不是所有都可以放在String变量里
    除了String类型变量VB中其他类型变量都只有几个字节长难道次只能发几个字节吗?那样岂不是要累死机器了!其实情况没有那么悲观我们完全可以使用来解决这个问题就是使用把要传送文件都读到然后发送出去如下:
FileName 为要传送文件名WinS为发送文件WinSockControl控件这是个发送端
Public Sub SendFile(FileName As String, WinS As Winsock)
Dim FreeF As Integer \'空闲文件号
Dim LenFile As Long \'文件长度
Dim bytData As Byte \'存放数据
FreeF = FreeFile \'获得空闲文件号
Open FileName For Binary As #FreeFile \'打开文件
DoEvents

LenFile = LOF(FreeFile) \'获得文件长度
ReDim bytData(1 To LenFile) \'根据文件长度重新定义大小
Get #FreeFile, , bytData \'把文件读入到
Close #FreeFile \'关闭文件
WinS.SendData bytData \'发送数据
End Sub

    接受端如下:

Private Sub Winsock1_DataArrival(ByVal sTotal As Long)
Dim bytData As Byte
Dim f
f = FreeFile
Open strFileName For Binary As #f
ReDim bytData(1 To sTotal)
Winsock1.GetData bytData
Put #f, i, bytData
i = i + sTotal \'保证每次写都是在文件末尾, i是个全局变量
Close #f
End Sub

    这里有两个需要注意地方ReDim Preserve bytData(1 To LenFile)下标是从1开始如果你写成ReDim bytData( LenFile)下标就是从0开始了就有LenFile+1长了LenFile = LOF(FreeFile)中LOF是获得文件长度是VB里带个人所见过很多例子用API或者循环读直到末尾来获取文件长度这样都是很麻烦使用LOF就可以了
    这样即可以传送文本文件也可以传送 2进制文件但是你有没有发现这个问题呢?如果我要传送个50M文件呢?系统可以为bytData分配50M内存空间吗?
    于是笔者拿个50M文件做实验吧接收到文件和原来文件不比原来问题出在那呢?
    首先根据文件大小重新定义bytData大小本身就有问题系统是不可能无限制分配空间即使可以也会造成系统响应变慢在传50M文件时候系统就跟死机了那么如何解决这个问题呢个自然想法就是把数据分段传送如下:
    发送, iPos是个全局变量,值为0这个变量保存着当前数据位置Const iMax = 65535是每个数据块大小


Dim FreeF As Integer \'空闲文件号
Dim LenFile As Long \'文件长度
Dim bytData As Byte \'存放数据
FreeF = FreeFile \'获得空闲文件号
Open FileName For Binary As #FreeF \'打开文件
DoEvents
LenFile = LOF(FreeF) \'获得文件长度
If LenFile <= iMax Then \'如果要发送文件小于数据块大小直接发送
ReDim bytData(1 To LenFile) \'根据文件长度重新定义大小
Get #FreeF, , bytData \'把文件读入到
Close #FreeF \'关闭文件
WinS.SendData bytData \'发送数据
Exit Sub
End If
\'文件大于数据块大小进行分块发送
Do Until (iPos >= (LenFile - iMax)) \'发送整块数据循环
ReDim bytData(1 To iMax)
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
iPos = iPos + iMax \'移动iPos使它指向下来要读数据
Loop
\'这里要注意必须检查文件有没有剩下数据如果文件大小正好等于数据块大小
\' 整数倍那么就没有剩下数据了
ReDim bytData(1 To LenFile - iPos) \'发送剩下不够个数据块数据
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
Close #FreeF

下面是接收端:
Private Sub Winsock1_DataArrival(ByVal sTotal As Long)
Dim bytData As Byte[Page]
Dim lLenFile As Long
Dim f
f = FreeFile
Open strFileName For Binary As #f \'strFileName是文件名
lLenFile = LOF(f)
ReDim bytData(1 To sTotal)
Winsock1.GetData bytData
If lLenFile = 0 Then \'lLenFile=0表示是第次打开文件这里有个问题就是\'如果如果该文件存在就会出错应该在打开前检查文件是否存在(这里我省略了)
Put #f, 1, bytData
Else
Put #f, lLenFile + 1, bytData
End If
Close #f
End Sub

Tags:  pbwinsock控件 winsock控件 winsock控件的使用 vbwinsock控件

延伸阅读

最新评论

发表评论