• 帮助
    • 博客
    • 相册
    • 网盘
    • 超市
    • Xer吧
  • 登录
  • 注册
【公告】斗秀网(doshoot.com)使用帮助指南    【公告】关于X5dj结合斗秀网上传图片的相关公告    【公告】X5dj网站网络硬盘用户使用协议    
  • 下一秒……纵横四海
  • http://www.x5dj.com/benx203 复制地址
  • 首页

  • 博客

  • 相册

  • 网盘

  • 人际关系网

loading...
VB使用ADODB操作数据库的常用方法 < 上一篇 下一篇 > VB编程实现Windows XP风格的界面
VB中使用WinSock控件传送文件
benx203 发表于: 2007-05-02 10:28 来源:转载  X度:0  浏览:(834)  评论:(2)
收藏 | 复制地址 | [举报此文章] |  大 中 小 |  引用 删除 修改

http://www.xren.net/program/11697.html

    传送文件对于网络编程来说是基本的功能,比如远程控制软件。在编制一个软件时,我从网上下了很多传文件的程序,这些程序提供的传文件功能根本就不能用。传文本还可以,传二进制文件根本就不行。因此,作为一个基本的功能模块,有必要单独介绍一下。
    首先,在VB中要传送字符串,你可以这样写:
Dim strData As String
strData = "Test"
Winsock1.SendData strData
    但是如果你传送的二进制文件,你还能用String变量来存放吗?从理论上分析是不行的,我也做了实验,确实是不行的。文件虽然可以传,但是接受的文件和发送的不一样,原因可能是二进制文件里可以有任何"字符",但是不是所有的字符都可以放在String变量里。
    除了String类型的变量,VB中其他类型的变量都只有几个字节长,难道一次只能发几个字节吗?那样岂不是要累死机器了!其实,情况没有那么悲观,我们完全可以使用数组来解决这个问题,就是使用byte数组。把要传送的文件都读到数组里,然后发送出去。程序如下:


FileName 为要传送的文件名,WinS为发送文件的WinSock控件。这是一个发送端的程序。
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 bytesTotal As Long)
Dim bytData() As Byte
Dim f
f = FreeFile
Open strFileName For Binary As #f
ReDim bytData(1 To bytesTotal)
Winsock1.GetData bytData
Put #f, i, bytData
i = i + bytesTotal '保证每次写都是在文件的末尾, 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函数就可以了。
    这样的程序,即可以传送文本文件,也可以传送二进制文件。但是你有没有发现这个程序的问题呢?如果我要传送一个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 bytesTotal As Long)
Dim bytData() As Byte
Dim lLenFile As Long
Dim f
f = FreeFile
Open strFileName For Binary As #f 'strFileName是文件名
lLenFile = LOF(f)
ReDim bytData(1 To bytesTotal)
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

 
系统分类:
推送: 无分类 归类:VB相关

安全是一种意识,而不是几个杀毒软件的名字.
 
VB使用ADODB操作数据库的常用方法 < 上一篇 下一篇 > VB编程实现Windows XP风格的界面
用户回复
游客:无名  发表于:2007-12-11 17:09  引用 删除 修改 (1楼)
谢谢
 
benx203  发表于:2007-12-11 19:13  引用 删除 修改 (2楼)
不客气 这也不是我写的
安全是一种意识,而不是几个杀毒软件的名字.
 
首页 上一页 1 下一页 尾页 共 1 页
评分与快速回复

博主推荐
相关文章
博友热推
  • 斗秀网生活全攻略使用帮助指南!
  • 离去的人总是牵扯着目送人的情感
  • 这样折磨学生的高考还要持续多久
  • X5dj结合斗秀网上传图的相关公告
  • 大四学子毕业时,都变成诗人一样
  • 以经济为中心的社会哪里还有爱情
  • 渴望如花朵般尽情地绽放我的爱情
  • 看<当幸福来敲门>感受活着的幸福
  • 诚意的帮忙换不来一句真诚的道谢
关于我们 | X5dj动态 | 加入我们 | 友情链接 | 官方日志 | 免责声明 | 举报不良信息
北京开创明天科技有限公司 版权所有 京ICP证040979号 京ICP备09009268号