高分请问VB使用WINSOCK利用HTTP上传二进制文件的问题

mtide 2005-12-12 01:03:54
一个通过HTTP提交文件的文章和代码:

http://www.vbforums.com/showthread.php?t=337424

上面这个例子好象是只能提交文本文件
因为他打开文件的时候是使用STRING类型数据接受了文件,弱弱问一句使用STRING接受二进制文件以后能当BYTE来使用的吗。。
而我测试过二进制好象是不成功的,希望能有熟VB的朋友帮忙测试一下

我试的方法是把文件用BYTE ARRAY读出来,然后SENDDATA到HTTP SERVER,但是SEND BYTE ARRAY的话,HTTP HEADER也要转化为BYTE了,这样整个BYTE ARRAY传上去,HTTP SERVER好象不能正确识别HEADER
而XMLHTTP也是传送BYTE,不过它有一个HEADER的属性和SENDDATA是独立分开的

应该怎么正确POST二进制文件呢。。?
...全文
589 点赞 收藏 13
写回复
13 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
51365133 2006-04-08
//调用方式
#include "socket.h"
#include "SktHead.h"
#include "stdio.h"

void get_send(char *strcd,char *buf);
void get_strip(char *strcd,struct Sock_Data &sock);

int main()
{
struct Sock_Data sock;
get_strip("001",sock);
int nRet=init_server(sock.sockip,sock.sockport);
if(!nRet)
printf("initserver error");
nRet=init_socket();
if(!nRet)
printf("init error");
nRet=creat_socket();
if(!nRet)
printf("creat error");
nRet=conn_socket();
if(!nRet)
{
printf("connect error");
system("pause");
return 0;
}

get_send("AABCDEFGHIABCDEFGHIABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\n01234567899876543210012345678912\nabcdefghijklmnopqrstuvwxyzabcdef\nABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF\n");

nRet=send_socket(data_buf);
if(!nRet)
printf("send error");
close_socket();

system("pause");
return 0;
}
void get_send(char *buf)
{
int size=strlen(buf);
if(data_buf.buf!=NULL)
delete data_buf.buf;
data_buf.buf=new char[size];
sprintf(data_buf.size,"%04d",size);
strcpy(data_buf.buf,buf);
}
void get_strip(char *strcd,struct Sock_Data &sock)
{
char Head[20];
sprintf(Head,"STRCD%s",strcd);
GetPrivateProfileString(Head,
"Server",
"172.22.1.8",
sock.sockip,
sizeof(sock.sockip),
".\\SockInfo.ini");
char tmp[20];
GetPrivateProfileString(Head,
"port",
"6667",
tmp,
sizeof(tmp),
".\\SockInfo.ini");
sock.sockport=atoi(tmp);
}
回复
51365133 2006-04-08
给你个 socket的封装

#include "socket.h"
#include "skthead.h"
#include "stdio.h"
#include <assert.h>

SOCKETEXPORT int init_socket()
{
WSADATA wsdData;
if(WSAStartup(0x202,&wsdData)!=0)
{
WSACleanup();
return 0;
}
if (LOBYTE(wsdData.wVersion)!=2 || HIBYTE(wsdData.wVersion) != 2)
{
WSACleanup();
return 0;
}
return 1;
}
SOCKETEXPORT int init_server(char *strip,int port)
{
if(strlen(strip)==0)
return 0;
strcpy(m_strip,strip);
m_port=port;
return 1;
}
SOCKETEXPORT int creat_socket()
{
char chInfo[64];

if (gethostname(chInfo, sizeof(chInfo)))
return 0;

sock = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sock==INVALID_SOCKET)
return 0;

return 1;
}
SOCKETEXPORT int conn_socket()
{
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr(m_strip);
local.sin_port=htons(m_port);

if(connect(sock,(sockaddr *)&local,sizeof(local))!=0)
{
WSACleanup();
return 0;
}
return 1;
}
SOCKETEXPORT int bind_socket()
{
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons(m_port);

if(bind(sock,(sockaddr *)&local,sizeof(local))!=0)
{
WSACleanup();
return 0;
}
return 1;
}
SOCKETEXPORT int read_socket(SOCKET m_ReadSock,struct databuf &buf_data)
{
recv(m_ReadSock,buf_data.size,4,0);
buf_data.size[4]='\0';
int size=atoi(buf_data.size);
if(data_buf.buf!=NULL)
delete buf_data.buf;
buf_data.buf=new char [size];
assert(data_buf.buf!=NULL);

memset(buf_data.buf,0,size);

int recvlen=recv(m_ReadSock,buf_data.buf,size,0);
buf_data.buf[size]='\0';

if(recvlen!=size)
return 0;
return 1;
}
SOCKETEXPORT int send_socket(struct databuf buf_data)
{
char *buf="";
int size=atoi(buf_data.size)+4;
buf=new char[size];
assert(buf!=NULL);
memset(buf,0,size);
strcat(buf,buf_data.size);
strcat(buf,buf_data.buf);
int sendlen=send (sock,buf,size,0);
int sendsize=strlen(buf);
delete buf;
if(sendlen!=sendsize)
return 0;
if(sendlen==0)
return 0;
return 1;
}
SOCKETEXPORT int accept_socket(SOCKET &m_ReadSock)
{
sockaddr_in from;
SOCKET m_socket=NULL;
int fromlen=sizeof(from);
m_ReadSock=accept(sock,(struct sockaddr*)&from,&fromlen);
if(m_ReadSock==INVALID_SOCKET)
return 0;
return 1;
}
SOCKETEXPORT void close_socket()
{
closesocket(sock);
}
SOCKETEXPORT int listen_socket()
{
if(listen(sock,5)!=0)
{
WSACleanup();
return 0;
}
return 1;
}
回复
EvAvis 2006-04-08
偶是用SOAP调用web Service服务实现的,很简单就实现了
Sub DownFiel()
Dim DonwStream() As Byte
Dim cc As New MSSOAPLib.SoapClient
cc.mssoapinit "http://10.232.208.102/Upfilesevice/Service1.asmx?WSDL"
DonwStream = cc.DownDocument(strCmd)
Dim WordPath As String
Dim StmWord As ADODB.Stream
On Error GoTo err
WordPath = App.Path & "\temp\" & strCmd & ".doc"
Set StmWord = New ADODB.Stream
With StmWord
.Type = adTypeBinary
.Open
.Write DonwStream '写入数据库中的数据至Stream中
.SaveToFile WordPath, adSaveCreateOverWrite '将Stream中数据写入临时文件中
.Close
End With
Exit Sub
err:
MsgBox ("错误")
End
End Sub


web Service 上只要接收这个二进制就行了
回复
of123 2006-04-07
我一直没有搞懂你说的文本和二进制的事情。数据在传送中就是一系列的 0 和 1,分不出文本和二进制的。关键在于你的解释。

实际上,你就用 Byte Array 发送就好。无非是包头、包尾用 ASCII 码。
回复
VBToy 2006-04-07
参考以下内容:

在VB中不能使用String变量处理二进制数据。早期的VB是采用单字节处理方式(通常也称为ANSI方式),也就说一个英文字母用一个字节表示,一个汉字算两个字节,当然这样就可能出现半个汉字的问题。从VB 4.0起,VB采用了一种新的处理方式,即内部采用Unicode方式,即不论英文字母还是汉字,一律用两个字节表示,但Unicode还不够普及,所以VB只是在其内部完全使用Unicode,而在外部仍转换为人们习惯的ANSI方式,但在字符串处理上与先前的版本有所不同。例如:在中文Windows或英文Windows外挂RichWin 97中,Len("电子&电脑")=5(这里的&号为半角字符),而在以前的版本或纯英文Windows中Len("电子&电脑")=9。除了Len、Left、Right等字符串函数受此影响外,所有字符操作都受此影响。如果你把二进制数据读入字符串变量,在读入的过程中会发生转换错误,这样你再写入文件数据也就不对了。以上的讨论对于中文等双字节系统都是适用的,但英文版下没有这个问题。所以,你在网上看到的许多程序因为都是美国人写的,他们根本就不考虑这个问题,使用字符串来处理二进制数据,但这样的程序在中文系统中肯定出错。解决的办法是使用Byte数组来处理二进制数据,这样就不会有你说的问题了。例如:
Dim n As Long
Dim arrBytes() As Byte

Open "c:\win98\setup.bmp" For Binary As 1
n = LOF(1)
ReDim arrBytes(1 To n) As Byte
Get 1, , arrBytes
Close 1

If arrBytes(1) = Asc("B") And arrBytes(2) = Asc("M") Then
MsgBox "这是一个位图文件。"
End If

类似的,由双字节引起的问题还有:
QA000388 "MSComm无法在中文Windows 95下传递二进制数据"
QA002682 "RegQueryValueEx函数返回二进制值到字符串出错"
QA003729 "利用Winsock控件下载ZIP文件,为什么下载后的文件大小不一致"
QA001156 "VB中的sp2,sp3,企业版这三种各代表什么含义"
QA002941 "VB6 好像不认识 ACCSEE 2000 的数据库"


回复
mrfinger 2006-04-07
之前有个方法就是把文件以二进制方式分块读取,然后发送,而头文件和结束则是以文本形式发送,但是我怎么测试好像服务器端都没办法接收到文件

-->>发送头文件(文本字符型)

-->>发送分块的二进制

-->>发送结束符号

就是用多个senddata

好像是接收不到文件,中间好像有个地方断掉了,很奇怪

回复
mrfinger 2006-04-07
关注这个问题,我最近也在测试这个问题,但是好像将二进制转成文本之后上传总是和原来的字符相差一些,比如上传的图片总是看不到,而上传的文本也总是多出一个正方形,所以这个问题还是很头疼。
回复
kmlxk0 2006-03-14
好东西~~收藏呀
回复
cgs1999 2006-03-14
下面是我写的一个通过HTTp协议上传文件的函数,接收端采用Servlet实现

'*************************************************************************
'**函 数 名:UploadFile
'**输 入:strFile 上传文件的本地路径
'**输 出:String 返回上传后的文件名称
'**功能描述:上传本地文件
'**全局变量:glngMaxFileSize,gstrServerUrl,gstrServletPath
'**调用模块:InitUpload
'**作 者:深渊
'**日 期:2006-03-05 10:44:00
'**修 改 人:
'**日 期:
'**版 本:V1.0.0
'**说 明:gstrServerUrl="http://127.0.0.1"; 服务器地址
'** :gstrServletPath = "/servlet/UploadFile" Servlet路径
'*************************************************************************
Public Function UploadFile(ByVal strFile As String) As String
On Error GoTo ErrHandle:
If FileLen(strFile) > glngMaxFileSize Then
MsgBox "文件大小超过 " & glngMaxFileSize & " 字节 ,不允许上传!", vbExclamation + vbOKOnly, "警告"
Exit Function
End If

Dim intPointer As Integer
intPointer = Screen.MousePointer
Screen.MousePointer = vbArrowHourglass

Dim strURL As String
strURL = gstrServerUrl & gstrServletPath
Dim intFile As Integer, lngLength As Long
Dim lngStart As Long, lngLeft As Long
Dim xmlhttp, strName As String
Dim vData, lngSend As Long, strResponse As String
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
strName = URLEncode(Mid(strFile, InStrRev(strFile, "\") + 1))
intFile = FreeFile()
Open strFile For Binary As #intFile
Do
lngLeft = LOF(intFile) - lngStart
If lngLeft <= 0 Then Exit Do
lngLength = IIf(lngLeft > SEGMENT_LENGTH, SEGMENT_LENGTH, lngLeft)
ReDim bytData(lngLength - 1) As Byte
Get #intFile, , bytData
vData = bytData
xmlhttp.Open "POST", strURL, False
xmlhttp.setRequestHeader "Content-File", strName
If lngStart > 0 Then
xmlhttp.setRequestHeader "Content-Start", lngStart
End If
xmlhttp.Send vData
strResponse = StrConv(xmlhttp.responseBody, vbUnicode)
If Not IsNumeric(strResponse) Then
Screen.MousePointer = intPointer
Exit Do
Else
lngSend = strResponse
End If
strName = xmlhttp.getResponseHeader("Content-File")
lngStart = lngStart + lngLength
If lngSend <> lngStart Then
Screen.MousePointer = intPointer
Exit Do
End If
Loop
Close #intFile
If lngLeft = 0 Then
UploadFile = URLDecode(strName)
End If

Screen.MousePointer = intPointer
Exit Function
ErrHandle:
Screen.MousePointer = intPointer
End Function

Public Function URLEncode(ByVal strInput As String, Optional ByVal blnNoPlus As Boolean) As String
Dim strChar As String
Dim intAscii As Integer
Dim i As Long
For i = 1 To Len(strInput)
strChar = Mid$(strInput, i, 1)
intAscii = Asc(strChar)
'处理"0" - "9", "a" - "z", "A" - "Z"
If ((intAscii < 58) And (intAscii > 47)) Or _
((intAscii < 91) And (intAscii > 64)) Or _
((intAscii < 123) And (intAscii > 96)) Then
URLEncode = URLEncode & strChar
Else
URLEncode = URLEncode & Hex2(CLng("&h" & Hex(intAscii)))
End If
Next
If Not blnNoPlus Then
URLEncode = Replace(URLEncode, "%20", "+")
End If
End Function
回复
godidea 2006-03-13
这里说的是 用 http协议
回复
faysky2 2006-03-13
vb中进行网络文件传输
http://community.csdn.net/Expert/FAQ/FAQ_Index.asp?id=205277
回复
godidea 2006-03-13
二进制没有搞定,关注中
回复
mtide 2005-12-12
...up by myself
回复
相关推荐
发帖
网络编程
创建于2007-09-28

1474

社区成员

VB 网络编程
申请成为版主
帖子事件
创建了帖子
2005-12-12 01:03
社区公告
暂无公告