vc++ socket http协议post方法上传(分块上传)

来源:互联网 发布:修改网页游戏数据 编辑:程序博客网 时间:2024/05/16 17:39
最近项目需要,通过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 plaincopyusing 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。

2 0
原创粉丝点击