vc++ socket http协议post方法上传(分块上传)
2014-02-20 13:01
274 查看
最近项目需要,通过C++客户端向Web服务器用http协议上传文件,网上介绍这方面的好像很少,所以做了个基础的发上来供学习交流; 本人学c++没几天,代码可能比较烂,大家凑合看吧。。 示例代码: 1、C++ Clinet [cpp] view plaincopy #include "stdio.h" #include "WinSock2.h" #include "iostream" using namespace std; #pragma comment(lib,"ws2_32.lib") long l_file_len; //获取文件内容 bool file_con(char **buffer,LPCSTR file) { FILE *fp = fopen(file, "rb"); if(fp==NULL) { printf("文件上传失败,请检查文件路径.....\n"); return false; } fseek(fp, 0, SEEK_END); l_file_len = ftell(fp); rewind(fp); *buffer = new char[l_file_len + 1]; memset(*buffer, 0, l_file_len + 1); fseek(fp, 0, SEEK_SET); fread(*buffer, sizeof(char), l_file_len, fp); fclose(fp); return true; } //文件上传 std::string upload(LPCSTR lpszServer,LPCSTR lpszAddr,LPCSTR fileUrl) { char *file = NULL; if(!file_con(&file,fileUrl)) { return "0"; } SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) return "0"; SOCKADDR_IN server; server.sin_family = AF_INET; server.sin_port = htons(80); struct hostent *host_addr = gethostbyname(lpszServer); if (host_addr == NULL) return "host_addr == NULL"; server.sin_addr.s_addr = *((int *) *host_addr->h_addr_list); if (::connect(sock, (SOCKADDR *) &server, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { ::closesocket(sock); return "0"; } printf("ip address = %s, port = %d\n",inet_ntoa(server.sin_addr), ntohs(server.sin_port)); std::string header(""); std::string content(""); //----------------------post头开始-------------------------------- header +="post "; header +=lpszAddr; header +=" HTTP/1.1\r\n"; header +="Host: "; header +=lpszServer; header += "\r\n"; header += "User-Agent: Mozilla/4.0\r\n"; header += "Connection: Keep-Alive\r\n"; header += "Accept: */*\r\n"; header += "Pragma: no-cache\r\n"; header += "Content-Type: multipart/form-data; charset=\"gb2312\"; boundary=----------------------------64b23e4066ed\r\n"; content += "------------------------------64b23e4066ed\r\n"; content += "Content-Disposition: form-data; name=\"file\"; filename=\"大论文和实验材料.rar\"\r\n"; content += "Content-Type: aapplication/octet-stream\r\n\r\n"; //post尾时间戳 std::string strContent("\r\n------------------------------64b23e4066ed\r\n"); char temp[64] = {0}; //注意下面这个参数Content-Length,这个参数值是:http请求头长度+请求尾长度+文件总长度 sprintf(temp, "Content-Length: %d\r\n\r\n", content.length()+l_file_len+strContent.length()); header += temp; std::string str_http_request; str_http_request.append(header).append(content); //----------------------post头结束----------------------------------- //发送post头 send(sock, str_http_request.c_str(), str_http_request.length(), 0); char fBuff[4096]; int nPacketBufferSize = 4096; // 每个数据包存放文件的buffer大小 int nStart;//记录post初始位置 int nSize;//记录剩余文件大小 // 就分块传送 for (int i = 0; i < l_file_len; i += nPacketBufferSize) { nStart=i; if (i + nPacketBufferSize + 1> l_file_len) { nSize = l_file_len - i; } else { nSize = nPacketBufferSize; } memcpy(fBuff, file + nStart, nSize); ::send(sock, fBuff, nSize, 0); Sleep(0.2); } ::send(sock,strContent.c_str(),strContent.length(),0); char szBuffer[1024] = {0}; while (true) { int nRet = ::recv(sock, szBuffer, sizeof(szBuffer), 0); if (nRet == 0 || nRet == WSAECONNRESET) { printf("Connection Closed.\n"); break; } else if (nRet == SOCKET_ERROR) { printf("socket error\n"); break; } else { printf("recv() returned %d bytes\n", nRet); printf("received: %s\n", szBuffer); break; } } ::closesocket(sock); delete [] file; return szBuffer; } void main() { WORD wVersionRequested=MAKEWORD(2,2); WSADATA wsaData; if(WSAStartup(wVersionRequested,&wsaData)) { cout<<"加载错误"<<endl; } if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wHighVersion)!=2) { cout<<"WinSock's 加载错误"<<endl; } upload("localhost","/WebApplication1/Default.aspx","F:\\postgresql-8.3.3-2.rar"); } 2、Web Server [csharp] view plaincopy using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Text; namespace WebApplication1 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (Request.Files.Count > 0) { try { HttpPostedFile file = Request.Files[0]; string filePath = Request.PhysicalApplicationPath + file.FileName; file.SaveAs(filePath); Response.Write("Success\r\n"); } catch { Response.Write("Error\r\n"); } Response.End(); } } } } 上面就是简单的代码示例,web需配置iis,相信大家知道怎么做^_^,还有一点就是web程序默认上传文件的限制,默认上传大小为4M,所以需要 在web.config中设置以下参数: [html] view plaincopy <httpRuntime maxRequestLength="951200" appRequestQueueLimit="60" executionTimeout="60"/> 这里的maxRequestLength即是默认的上传文件大小,单位是KB。
相关文章推荐
- vc++ socket http协议post方法上传(分块上传)
- VC编写自己构造http协议数据的post上传图片类
- VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)(转)
- VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)
- VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)(转)
- VC编写自己构造http协议数据的post上传图片类(MFC环境 带编码转换)(转)
- VC++ Post 方法 上传数据到web服务器
- Android学习笔记---28_网络通信之通过HTTP协议实现文件上传,组拼http 的post方法,传输内容
- php另类上传图片的方法(PHP用Socket上传图片)
- 网络协议学习——HTTP协议POST方法的格式
- vc中如何通过http的post方式上传文件
- VC弹出IE网页附带POST数据的方法
- FTP上传时数据Socket错误连接超时的解决方法
- FTPClient 上传文件调用storeFile方法SocketException问题
- VC++下实现Socket编程方法
- 使用Curl、socket、file_get_contents三种方法POST提交数据
- Android开发 post方法上传数值及汉字编码
- 纯vc sdk实现http post 方式上传数据到web服务器
- 纯vc sdk实现http post 方式上传数据到web服务器
- Retrofit的POST方法上传头像