小弟遇到一问题,在winsock1_DataArrival事件中,我写入了以下代码,,. Winsock1.GetData DATA, vbString '得到数据 Dim Pos%, LENGTH%, HEAD$
Pos = InStr(DATA, vbCrLf & vbCrLf) '得到头结束的位置
LENGTH = Len(DATA) '整个数据的长度
HEAD = Left(DATA, Pos - 1) '得到头的字符串
DATA = Right(DATA, LENGTH - Pos - 3) '除掉头外的剩下数据段
BytesRemaining = 507558 '通过其他方法得到的文件实际大小'-----------开始写数据到文件--------
If BytesAlreadySent < BytesRemaining + 1 Then
'------BytesAlreadySent表示在本地下载文件的写入点
Open FilePathName For Binary Access Write As #1
'------FilePathName 为本地存放的地址与文件名的变量(如:c:\t.exe)
Put #1, BytesAlreadySent, DATA
BytesAlreadySent = BytesAlreadySent + bytesTotal
Close #1
End If
'-----------------------------------以上的程序预想现实文件的下载操作,但实际情况却是:下载下来的文件比实际大了一百多个字节。或十一个字节,或小一百多个字节。
请各位大侠帮帮小弟我的忙!!!谢了先
Pos = InStr(DATA, vbCrLf & vbCrLf) '得到头结束的位置
LENGTH = Len(DATA) '整个数据的长度
HEAD = Left(DATA, Pos - 1) '得到头的字符串
DATA = Right(DATA, LENGTH - Pos - 3) '除掉头外的剩下数据段
BytesRemaining = 507558 '通过其他方法得到的文件实际大小'-----------开始写数据到文件--------
If BytesAlreadySent < BytesRemaining + 1 Then
'------BytesAlreadySent表示在本地下载文件的写入点
Open FilePathName For Binary Access Write As #1
'------FilePathName 为本地存放的地址与文件名的变量(如:c:\t.exe)
Put #1, BytesAlreadySent, DATA
BytesAlreadySent = BytesAlreadySent + bytesTotal
Close #1
End If
'-----------------------------------以上的程序预想现实文件的下载操作,但实际情况却是:下载下来的文件比实际大了一百多个字节。或十一个字节,或小一百多个字节。
请各位大侠帮帮小弟我的忙!!!谢了先
http://www.21code.com/codebase/?pos=down&id=1920
你的代码问题在于你传输时是用字符串传输,应该使用Byte数组类型传输
在网络传输中都是使用ANSI传输的
所以你的头上的两行可以这样写
dim Bt_RecieveByte() as byte
Winsock1.GetData Bt_RecieveByte(), vbbyte
然后直接将其写入以二进制方式打开的文件中
--------------------------------------------
HTTP/1.1 200 OK
Date: Wed, 07 Jan 2004 23:54:34 GMT
Server: Apache/1.3.22 (Unix) (Red-Hat/Linux) mod_ssl/2.8.12 OpenSSL/0.9.6b DAV/1.0.3 PHP/4.1.2 mod_perl/1.26
Last-Modified: Sun, 04 Jan 2004 06:46:00 GMT
ETag: "540c9-7bea6-3ff7b6a8"
Accept-Ranges: bytes
Content-Length: 507558
Connection: close
Content-Type: text/plain--------------------------------------------
而Content-Length: 507558就是原始文件的大小,如果用byte方式,就不能得到该信息,请问我还能通过其他方式得到原始文件的大小吗?
即第一次传输字符串,第二次传输Byte数据
如果是别人的服务端
那你只有可以用Byte数组接受
然后写一个Byte转字符串的数据,得到文件大小,再接受其他Byte数据写入文件
转字符串可以这样写
dim Bt_RecieveByte() as byte
dim i as integer
Static StrHeader as string
Winsock1.GetData Bt_RecieveByte(), vbbyte
do while instr(1,Strheader, "Content-Type") Strheader=Strheader+cstr(Bt_RecieveByte(i))
i=i+1 loop当找到"Content-Type"字符串以后,你就可以再Strheader字符串中找到文件大小了
是do while not instr(1,Strheader, "Content-Type")代码没做测试,只是说明思路,你自己再看看吧
----------------------------------------------------------------------
Private Sub winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
ReDim bytData(bytesTotal) Winsock1.GetData bytData, vbByte
Open FilePathName For Binary As #1 'opens file for output
Put #1, BytesAlreadySent, bytData 'writes data to the end of file
BytesAlreadySent = BytesAlreadySent + bytesTotal
Close #1
End Sub'------------------------------------------------------------------------------我只有一个客户端,没有服务器端,就是一个直接从服务器中相应的目录下面下载文件的操作
估计与connect事件写的有关系,请看看我的connect事件有问题吗?
---------------------------------------------------------
Private Sub winsock1_Connect()
Dim strCommand As String
On Error Resume Next strCommand = "GET " + URL + " HTTP/1.0" + vbCrLf '其中URL为下载的URL
strCommand = strCommand + "Accept: *.*, */*" + vbCrLf
strCommand = strCommand + "User-Agent: Conquest" & vbCrLf
strCommand = strCommand + "Referer: " & strSvrURL & vbCrLf
strCommand = strCommand + vbCrLf
Winsock1.SendData strCommand
End Sub
----------------------------------------
Private Sub winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
ReDim bytData(bytesTotal) '定义一个数组存放每次发送来的数据。 Dim tmpData() As Byte '保存第一次发送来的数据去掉头部信息后的数据
Dim DATA As String '保存二进制转为字符串时的字符串
Winsock1.GetData bytData, vbByte + vbArray
DATA = StrConv(bytData, vbUnicode) '二进制转为字符串
If InStr(DATA, "Content-Type:") Then
Dim Pos%, LENGTH%, HEAD$
Pos = InStr(DATA, vbCrLf & vbCrLf)
LENGTH = Len(DATA)
HEAD = Left(DATA, Pos - 1)
DATA = Right(DATA, LENGTH - Pos - 3)
Header = Header & HEAD
bytesRemaining = GETDATAHEAD(Header, "Content-Length:") '得到文件的大小
tmpData = StrConv(DATA, vbFromUnicode) '字符串转为二进制 '第一次写文件(去掉头后的数据写入指定文件中)
Open FilePathName For Binary As #1
Put #1, BytesAlreadySent, tmpData() 'writes data to the end of file
BytesAlreadySent = Seek(1)
Close #1
Exit Sub
End If '将得到的数据写入文件
Open FilePathName For Binary As #1
Put #1, BytesAlreadySent, bytData
BytesAlreadySent = Seek(1)
Close #1End Sub
--------------------------------------------------------------------
我感觉错误不像你说的那样,不是回车少什么字符了
而是代码Put #1, BytesAlreadySent, bytData 应该改为
Put #1, BytesAlreadySent+1, bytData
而且我觉得你不必要每次在有数据来时判断"Content-Type:",只要找到一次后,下次就不必再判断了,这样能够提高效率
真是百思不得一解!!!盼高人指点!!!
好象是自动把文件里的回车替换为了换行加回车!(vbcrlf),这是为什么?!!!
Private Sub winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
ReDim bytData(bytesTotal) '定义一个数组存放每次发送来的数据。 Dim tmpData() As Byte '保存第一次发送来的数据去掉头部信息后的数据
Dim DATA As String '保存二进制转为字符串时的字符串
Winsock1.GetData bytData, vbByte + vbArray
************
DATA = StrConv(bytData, vbUnicode) '二进制转为字符串
如果说出现你说的vbcrlf的问题,就是在这条语句上出问题了,可能该函数是传址调用函数,会修改你的bytdata
*************
If InStr(DATA, "Content-Type:") Then
Dim Pos%, LENGTH%, HEAD$
Pos = InStr(DATA, vbCrLf & vbCrLf)
LENGTH = Len(DATA)
HEAD = Left(DATA, Pos - 1)
DATA = Right(DATA, LENGTH - Pos - 3)
Header = Header & HEAD
bytesRemaining = GETDATAHEAD(Header, "Content-Length:") '得到文件的大小
tmpData = StrConv(DATA, vbFromUnicode) '字符串转为二进制 '第一次写文件(去掉头后的数据写入指定文件中)
Open FilePathName For Binary As #1
*****************************
Put #1, BytesAlreadySent, tmpData() 'writes data to the end of file
如果你的BytesAlreadySent初值为1,则这条语句是对的
但是还是建议你将BytesAlreadySent初值为0,将该语句改为
Put #1, BytesAlreadySent+1, tmpData()
*****************************
*****************************
BytesAlreadySent = Seek(1)
你看看MSDN,Seek语句是获得当前文件的操作位置
*****************************
Close #1
Exit Sub
End If '将得到的数据写入文件
Open FilePathName For Binary As #1
************************** Put #1, BytesAlreadySent, bytData
所以,在下一次写入数据时,应该在上一次的位置上加1,在写入,否则会覆盖掉一个Byte,使文件变小
所以我还是建议改为 Put #1, BytesAlreadySent+1, bytData ***************************
BytesAlreadySent = Seek(1)
Close #1End Sub