如果要传送的文件不是非常大的话,其实可以在服务端一次性把文件读出来(用二进制方式打开),这时服务端先发一个要传送的文件的大小消息给客户端,当接收到客户端传来的一个应答消息后就可以开始传送文件了.此时客户端在接收文件时判断接收到的数据总和(因为不可能一下子就能接收完数据)是不是同刚才发来的文件大小一样大,如是则文件接收完,此时就发一个接收完文件的消息给服务端,这时服务端接收到这个消息后就可以发出一个接收完成的消息了.
下面是我的一个程序的一些代码:
一些说明:在这假设服务端和客户端已经连接好
服务端:
Text1是存放要传送文件的全路径(包括文件名,假设文件存在)
command1是确定传送文件
winsock1控件是用来传递消息的
winsock2是用来传送文件
客户端:
winsock1传递消息
winsock2接收文件
服务端代码如下:
dim GetFile() as byte
Private Sub Command1_Click()
winsock1.senddata "+SF "+文件名 '先发一个要传送的文件名过去,让对方知道这是什么文件
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim Sdata As String
Winsock1.GetData Sdata
GetCmd Sdata '得到消息
End Sub
Private Sub GetCmd(CmdText As String)
Select Case Left(CmdText, 3)
case "+GS" '对方要求知道文件大小的消息
Winsock1.SendData "+FS " + cstr(filelen(text1.text)) '发送一个传送文件大小的消息
case "+SF" '可以发送文件
SendFile
case "+SC" '发送完成
SendComple
end select
end sub
private sub SendFile()
on text1.text for binary as #1
ReDim GetFile(loc(1)) '在原来要定义好这个数组类型
Get #1, , GetFile
Close
Winsock2.SendData GetFile '发送文件的数据
end sub
private sub SendComple()
msgbox " 文件传送完成!"
end sub
客户端代码:
dim FileSize as long,GetFile() as byte,GetCount as long,Filename as string
Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim Sdata As String
Winsock1(1).GetData Sdata
GetCmd Sdata
End Sub
Private Sub GetCmd(CmdText As String)
Select Case Left(CmdText, 3)
case "+SF"
Filename=mid(cmdtext,5)
winsock1.senddata "+GS" '要求知道文件的大小
case "+FS" '得到文件的大小
AccpetFile CmdText
end select
end sub
private sub AccpetFile(msg as string)
FileSize=val(mid(msg,5))
open "C:\Temp\"+Filename for binary as #2 '相同机子测试时用2
winsock1.senddata "+SF" '可以开始发送文件了
GetCount=0
end sub
Private Sub Winsock2_DataArrival(Index As Integer, ByVal bytesTotal As Long)
ReDim GetFile(bytesTotal)
GetCount = GetCount + bytesTotal
Winsock2.GetData GetFile, vbByte, bytesTotal
Put #2, , GetFile
If Int(GetCount / 1024) = Int(Filesize / 1024) Then
GetCount = 0
msgbox "文件接收成功!!"
Winsock2.Close
Winsock1(1).SendData "+SC"
Close
End If
End Sub