大家好,又见面了,我是你们的朋友全栈君。在公司实习了一个周,虽然很累,但也感觉有所得,此次项目是做一个局域网两台计算机之间的文件传输。我用的主要控件为winsock控件,用其TCP协议。至于用此控件连接两台计算机书上都有介绍,我主要介绍一下我传送文件的思想和方法:
首先,将要传送的文件分成指定大小的N个包,大小不能超过8K因为TCP每次最多发送8K数据,最后一个包可能会小于其它包。然后在每个包加个包头,因为接收端需要通过包头知道传送过来的是数据还是路径(因为发送端指定存放路径),接收端收到数据后必须返回确认到发送端,这样才能循环发送,但一定要有最后的终止,不然会死循环。我的主要发送和接收代码如下:
发送端收到数据后产生的事件
Private Sub WskCli_DataArrival(ByVal bytesTotal As Long)
Dim FIT As Boolean, OVER As Boolean, xx As Byte
WskCli.GetData FIT
If Number < BagNum Then
If FIT = True Then ‘接收端已收到上一个数据包
If v <> 0 Then ‘传送速率受限制
Dim ss As Long
ss = 0
Do Until (Number * 1024 <= v * ss) ‘传送速率过大则等待
ss = CLng((Time – timeInt) * 3600 * 24)
Loop
End If
Send_File ‘调用发送文件数据包过程
End If
Number = Number + 1 ‘计数
ProgressBar1.Value = Number * 20 / BagNum ‘刷新进度条的进度
El**
*x = 2
WskCli.SendData xx ‘发送传送完毕的信息给接收端
Close 1
Label1.Caption = “发送完毕!”
OVER = True
Number = 0 ‘传送完后置计数Number=0
End If
If OVER = True Then ‘传送完之后的处理
Drive1.Enabled = True
Dir1.Enabled = True
File1.Enabled = True
CmdSend.Enabled = True
Exit Sub
End If
End Sub
send_file是自定义的一个发送过程:
Private Sub Send_File()
Dim i As Long ‘循环变量
If Number <= BagNum – 1 Then
ReDim Buff(1 To BagSize) As Byte ‘定义缓冲区
ReDim TempBuff(0 To BagSize) As Byte
Get 1, , Buff
TempBuff(0) = 1 ‘设置包头为1代表文件数据
For i = 1 To BagSize
TempBuff(i) = Buff(i)
Next
WskCli.SendData TempBuff
Else
‘传送最后一个数据包
n = filelength – Seek(1) + 1 ‘得到最后一个包的大小
If n > 0 Then
ReDim Buff(0 To n) As Byte
ReDim TempBuff(0 To n) As Byte
TempBuff(0) = 1 ‘设置包头为1代表文件数据
Get 1, , Buff
For i = 1 To n
TempBuff(i) = Buff(i – 1)
Next
WskCli.SendData TempBuff
End If
End If
End Sub
‘发送按钮被按下的响应事件
Private Sub CmdSend_Click()
CmdSend.Enabled = False
Combo1.Enabled = False
If Combo1.Text = “” Then
MsgBox “请选择一个传输速度!”, vbOKOnly, “错误”
Else
‘传送速度的选择
Select Case Combo1.ListIndex
Case 0
v = CLng(200) * 1024
Case 1
v = CLng(600) * 1024
Case 2
v = 1.5 * CLng(1024) * 1024
Case 3
v = 2 * CLng(1024) * 1024
Case 4
v = 0
End Select
If Number > 0 Then
‘重传或续传
If MsgBox(“上次未能传送完成,是否续传?”, vbYesNo, “提示”) = vbNo Then Number = 0: Close 1
End If
ReDim Buff(Len(sendFileName)) As Byte
Buff(0) = 0
For i = 1 To Len(sendFileName)
Buff(i) = Asc(Mid(sendFileName, i, 1))
Next
WskCli.SendData Buff ‘发送文件路径和文件名
End If
Open fn For Binary Access Read As #1
‘设置数据包的数量
filelength = LOF(1) ‘文件长度
BagNum = filelength / BagSize
If BagNum < filelength / BagSize Then BagNum = BagNum + 1
‘计时初始化
timeInt = Time
End Sub
接收端接收数据的事件:
Private Sub WskSer_DataArrival(ByVal bytesTotal As Long)
Dim Buff() As Byte ‘定义接收数据缓冲区
Dim OVER As Boolean ‘结束标记
WskSer.GetData Buff ‘接收数据
‘判断包头信息
Select Case Buff(0) ‘包头
Case 0
‘得到存放路径和文件名
fn = “”
For i = 1 To UBound(Buff)
fn = fn + Chr(Buff(i))
Next
Open fn For Binary As #1 ‘新建或打开文件
Close 1
Label1.Caption = “正在发送”
Case 1
‘写入文件
Open fn For Binary Access Write As #1
Seek #1, LOF(1) + 1 ‘找到文件尾
ReDim TempBuff(1 To UBound(Buff)) As Byte
‘去掉包头
For i = 1 To UBound(Buff)
TempBuff(i) = Buff(i)
Next
Put 1, , TempBuff ‘将数据写入文件
Close 1
Case 2
‘接收结束
Label1.Caption = “发送完毕!”
OVER = True
End Select
If OVER = True Then Exit Sub ‘如果接收完毕则退出此过程
WskSer.SendData True ‘告诉客户端继续发送下一个数据包
End Sub
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/135923.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...