VB实现局域网内的文件传输
发表于:2007-06-30来源:作者:点击数:
标签:
为了设计统一和用户操作方便,我们希望将服务端与客户端融合在一起,形成一个程序,这样用户理解起来,更加直观一点(其实这样做也是为了方便调试,大家可以在本机上 测试 ,自己传文件给自己)。所以,我们在程序中需要使用两个Winsock控件,一个负责监听,
为了设计统一和用户操作方便,我们希望将服务端与客户端融合在一起,形成一个程序,这样用户理解起来,更加直观一点(其实这样做也是为了方便调试,大家可以在本机上
测试,自己传文件给自己)。所以,我们在程序中需要使用两个Winsock控件,一个负责监听,一个负责发送,当发送端连接成功以后,便选择一个待发送的文件(可以是任意二进制文件),接着将文件名和文件字节长度发送给接收端,接收端收到这个消息以后,将文件名和文件长度解析出来,然后通知发送端可以开始发送文件;发送端读到这个消息之后,将文件流以字节的形式发送到接收端,接收端收到后,将二进制流回写,保存成文件即可。这里要注意两点,一个是由于Winsock每次最大传输8K的内容,所以需要将文件分解,每次传输固定数目的字节流,这样发送和接收时都可以根据这个数目来判断文件传输的进程,一旦字节流数目等于文件的大小,就需要关闭相应的文件句柄;另一点是由于我只使用一个Winsock控件接收,接收文本时需要注意要将UNICODE转码,解析成可识别的信息。
源代码
@#下面的代码既是
服务器又是客户端
@#采用应答式发送方式
@#自动拆分文件,包括2进制
Option Explicit
@#Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Dim mybyte() As Byte @#发送方数组
Const filecomesMSG = "a file is coming " @#有文件到来
Const RemoteIsReadyMSG = "sender is ready " @#准备好了
Const FileisOverMSG = "the file is ended" @#文件完毕
Const RemoteDenyMSG = "the user canceled" @#用户取消
Const filecountMSG = "the file lengh is" @#文件长度
Const RecevieIsReadyMSG = "Receiver is ready " @#准备接收
Dim arrdata() As Byte @#收到的信息
Dim filesave As Integer @#保存文件的句柄
Dim filehandle As Integer @#发送方文件的句柄
Dim FileSize As Double @#文件的大小
Dim Sendbyte As Long
Dim Receivebyte As Long
Dim MyLocation As Double
Dim myMSG As String @#消息
Dim FileisOver As Boolean @#文件是否已经完毕
Const ReceivePort = 7905
Const BUFFER_SIZE = 5734
Private Sub cmdConnect_Click()
Timer2.Enabled = True
End Sub
Private Sub cmdsend_Click()
On Error GoTo errorhandle
With CommonDialog1
.CancelError = True
.DialogTitle = "选择您要传送的文件"
.Filter = "All Files (*.*)|*.*"
.ShowOpen
End With
filehandle = FreeFile
Open CommonDialog1.FileName For Binary A
clearcase/" target="_blank" >ccess Read As #filehandle
cmdSend.Enabled = False
FileSize = CDbl(FileLen(CommonDialog1.FileName))
Label1.Caption = "等待回应>>>"
MsgBox ("选择的文件大小为 " & LOF(filehandle) & " 字节")
If WinsockSend.State = sckConnected Then
WinsockSend.SendData filecomesMSG & CommonDialog1.FileName @#发送发出文件信息
End If
Exit Sub
errorhandle:
cmdSend.Enabled = True
MsgBox ("你没有选择一个文件!")
End Sub
Private Sub Form_Load()
WinsockReceive.LocalPort = ReceivePort
WinsockReceive.Listen
FileisOver = True
Label1.Caption = "准备传输>>>"
End Sub
Public Function SendChunk()
Dim mybytesize As Long
If WinsockSend.State <> sckConnected Then Exit Function
mybytesize = BUFFER_SIZE
If LOF(filehandle) - Loc(filehandle) < BUFFER_SIZE Then mybytesize = (LOF(filehandle) - Loc(filehandle))
ReDim mybyte(0 To mybytesize - 1)
Get #filehandle, , mybyte
WinsockSend.SendData mybyte
Sendbyte = Sendbyte + mybytesize
ProgressBar1.Value = Int((100 / FileSize) * Sendbyte)
If Sendbyte >= FileSize Then
FileisOver = True
WinsockSend.SendData FileisOverMSG
End If
End Function
Private Sub Timer2_Timer()
If WinsockSend.State = sckConnected Then
Timer2.Enabled = False
cmdConnect.Enabled = False
ElseIf WinsockSend.State <> 1 And WinsockSend.State <> 6 And WinsockSend.State <> 7 And WinsockSend.State <> 8 And WinsockSend.State <> 9 Then
WinsockSend.Connect txtHost.Text, ReceivePort
ElseIf WinsockSend.State = 8 Or WinsockSend.State = 9 Then
WinsockSend.Close
End If
End Sub
Private Sub WinsockReceive_ConnectionRequest(ByVal requestID As Long)
If WinsockReceive.State <> sckClosed Then WinsockReceive.Close
WinsockReceive.Accept requestID
End Sub
Private Sub WinsockReceive_DataArrival(ByVal bytesTotal As Long)
ReDim arrdata(0 To bytesTotal - 1)
WinsockReceive.GetData arrdata,
vbByte + vbArray
myMSG = StrConv(arrdata, vbUnicode) @#二进制转为字符串
Select Case Mid(myMSG, 1, 17)
Case filecomesMSG @#这些消息发送方和接受方都可收到
@#显示保存对话框
On Error GoTo errorhandle
CommonDialog1.FileName = Mid(myMSG, 17, Len(myMSG))
CommonDialog1.DialogTitle = "选择保存文件的路径"
CommonDialog1.ShowSave
filesave = FreeFile
Receivebyte = 0
cmdSend.Enabled = False
WinsockReceive.SendData RecevieIsReadyMSG
Case FileisOverMSG
Close #filesave
MsgBox ("文件传输成功!") @#大家一起处理
cmdConnect.Enabled = True
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
ProgressBar1.Value = 0
WinsockReceive.SendData FileisOverMSG
WinsockReceive.Close
WinsockReceive.Listen
Case filecountMSG
FileSize = Mid(myMSG, 18, Len(myMSG))
Open CommonDialog1.FileName For Binary Access Write As #filesave
WinsockReceive.SendData RemoteIsReadyMSG
Label1.Caption = "文件准备传输!"
FileisOver = False
Case Else
If Receivebyte < FileSize Then
Receivebyte = Receivebyte + bytesTotal
Put #filesave, , arrdata
WinsockReceive.SendData RemoteIsReadyMSG
ProgressBar1.Value = Int((100 / FileSize) * Receivebyte)
End If
End Select
Exit Sub
errorhandle:
WinsockReceive.SendData RemoteDenyMSG
cmdConnect.Enabled = True
End Sub
Private Sub WinsockSend_DataArrival(ByVal bytesTotal As Long)
WinsockSend.GetData myMSG
Select Case myMSG
Case RecevieIsReadyMSG
WinsockSend.SendData filecountMSG & FileSize
FileisOver = False
Sendbyte = 0
Case RemoteIsReadyMSG
@#如果文件还没有结束,继续传输
If Not FileisOver Then
Label1.Caption = "文件正在被传输>>>"
SendChunk
Else
WinsockSend.SendData FileisOverMSG
End If
Case FileisOverMSG
@#主机处理
Close #filehandle
MsgBox ("文件传输成功!") @#大家一起处理
WinsockSend.SendData FileisOverMSG
WinsockSend.Close
cmdConnect.Enabled = True
ProgressBar1.Value = 0
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
Case RemoteDenyMSG
MsgBox ("用户终止了传输!")
cmdSend.Enabled = True
Label1.Caption = "准备传输>>>"
Close #filehandle
End Select
Exit Sub
End Sub
原文转自:http://www.ltesting.net