
外网:
1、创建FTP服务器,设置端口雀游转山岁闹发
2、使用windows自带的wininet.dll库,进行FTP下载和上传
具体代码比较多,如果需要可以私信联系方式,给你发
在网络编程过程中需要向服务器上传文件。Multipart/form-data是上传文件的一种方式。Multipart/form-data其实就是浏览器用表单上传文件的方式。最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。
表单形式上传附件
具体的步骤是怎样的呢?
首先,客户端和服务器建立连接(TCP协议)。
第二,客户端可以向服务器端发送数据。因为上传文件实质上也是向服务器端发送请求。
第三,客户端按照符合“multipart/form-data”的格式向服务器端发送数据。
既然Multipart/form-data格式就念败是浏览器用表单提交数据的格式,我们就来看看文件经过浏览器编码后是什么样子。
点击“Browse…”分别选择“unknow.gif”和“unknow1.gif”文件,点击“submit”按纽后,文件将被上传到服务器。
下面是服务器收到的数据:
服务器收到的数据
这是一个POST请求。所以数据是放在请求体内,而不是请求头内。
这行指出这个请求是“multipart/form-data”格式的,且“boundary”是 “---------------------------7db15a14291cce”这个行瞎字符串。
不难想象,“boundary”是用来隔开表单中不同部分数据的。例子中的表单就有 2 部分数据,用“boundary”隔开。“boundary”一般由系统随机产生,但也可以简单的用“-------------”来代替。
实际上,每部分数据的开头都是由"--"仔带颤 + boundary开始,而不是由 boundary 开始。仔细看才能发现下面的开头这段字符串实际上要比 boundary 多了个 “--”
紧接着 boundary 的是该部分数据的描述。
接下来才是数据。
“GIF”gif格式图片的文件头,可见,unknow1.gif确实是gif格式图片。
在请求的最后,则是 "--" + boundary + "--" 表明表单的结束。
需要注意的是,在html协议中,用 “\r\n” 换行,而不是 “\n”。
下面的代码片断演示如何构造multipart/form-data格式数据,并上传图片到服务器。
//---------------------------------------
// this is the demo code of using multipart/form-data to upload text and photos.
// -use WinInet APIs.
//
//
// connection handlers.
//
HRESULT hr
HINTERNET m_hOpen
HINTERNET m_hConnect
HINTERNET m_hRequest
//
// make connection.
//
...
//
// form the content.
//
std::wstring strBoundary = std::wstring(L"------------------")
std::wstring wstrHeader(L"Content-Type: multipart/form-data, boundary=")
wstrHeader += strBoundary
HttpAddRequestHeaders(m_hRequest, wstrHeader.c_str(), DWORD(wstrHeader.size()), HTTP_ADDREQ_FLAG_ADD)
//
// "std::wstring strPhotoPath" is the name of photo to upload.
//
//
// uploaded photo form-part begin.
//
std::wstring strMultipartFirst(L"--")
strMultipartFirst += strBoundary
strMultipartFirst += L"\r\nContent-Disposition: form-dataname=\"pic\"filename="
strMultipartFirst += L"\"" + strPhotoPath + L"\""
strMultipartFirst += L"\r\nContent-Type: image/jpeg\r\n\r\n"
//
// "std::wstring strTextContent" is the text to uploaded.
//
//
// uploaded text form-part begin.
//
std::wstring strMultipartInter(L"\r\n--")
strMultipartInter += strBoundary
strMultipartInter += L"\r\nContent-Disposition: form-dataname=\"status\"\r\n\r\n"
std::wstring wstrPostDataUrlEncode(CEncodeTool::Encode_Url(strTextContent))
// add text content to send.
strMultipartInter += wstrPostDataUrlEncode
std::wstring strMultipartEnd(L"\r\n--")
strMultipartEnd += strBoundary
strMultipartEnd += L"--\r\n"
//
// open photo file.
//
// ws2s(std::wstring)
// -transform "strPhotopath" from unicode to ansi.
std::ifstream *pstdofsPicInput = new std::ifstream
pstdofsPicInput->open((ws2s(strPhotoPath)).c_str(), std::ios::binary|std::ios::in)
pstdofsPicInput->seekg(0, std::ios::end)
int nFileSize = pstdofsPicInput->tellg()
if(nPicFileLen == 0)
{
return E_ACCESSDENIED
}
char *pchPicFileBuf = NULL
try
{
pchPicFileBuf = new char[nPicFileLen]
}
catch(std::bad_alloc)
{
hr = E_FAIL
}
if(FAILED(hr))
{
return hr
}
pstdofsPicInput->seekg(0, std::ios::beg)
pstdofsPicInput->read(pchPicFileBuf, nPicFileLen)
if(pstdofsPicInput->bad())
{
pstdofsPicInput->close()
hr = E_FAIL
}
delete pstdofsPicInput
if(FAILED(hr))
{
return hr
}
// Calculate the length of data to send.
std::string straMultipartFirst = CEncodeTool::ws2s(strMultipartFirst)
std::string straMultipartInter = CEncodeTool::ws2s(strMultipartInter)
std::string straMultipartEnd = CEncodeTool::ws2s(strMultipartEnd)
int cSendBufLen = straMultipartFirst.size() + nPicFileLen + straMultipartInter.size() + straMultipartEnd.size()
// Allocate the buffer to temporary store the data to send.
PCHAR pchSendBuf = new CHAR[cSendBufLen]
memcpy(pchSendBuf, straMultipartFirst.c_str(), straMultipartFirst.size())
memcpy(pchSendBuf + straMultipartFirst.size(), (const char *)pchPicFileBuf, nPicFileLen)
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen, straMultipartInter.c_str(), straMultipartInter.size())
memcpy(pchSendBuf + straMultipartFirst.size() + nPicFileLen + straMultipartInter.size(), straMultipartEnd.c_str(), straMultipartEnd.size())
//
// send the request data.
//
HttpSendRequest(m_hRequest, NULL, 0, (LPVOID)pchSendBuf, cSendBufLen)
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)