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

最近项目需要,通过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("文件上传失败,请检查文件路径.....
");  
      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
",inet_ntoa(server.sin_addr), ntohs(server.sin_port));     
      
    std::string header("");     
    std::string content("");     
//----------------------post头开始--------------------------------  
    header +="post ";  
    header +=lpszAddr;  
    header +=" HTTP/1.1
";  
    header +="Host: ";  
    header +=lpszServer;  
    header += "
";  
    header += "User-Agent: Mozilla/4.0
";  
    header += "Connection: Keep-Alive
";  
    header += "Accept: */*
";  
    header += "Pragma: no-cache
";  
    header += "Content-Type: multipart/form-data; charset="gb2312"; boundary=----------------------------64b23e4066ed
";  
  
    content += "------------------------------64b23e4066ed
";     
    content += "Content-Disposition: form-data; name="file"; filename="大论文和实验材料.rar"
";     
    content += "Content-Type: aapplication/octet-stream

";     
  
    //post尾时间戳  
    std::string strContent("
------------------------------64b23e4066ed
");  
    char temp[64] = {0};   
    //注意下面这个参数Content-Length,这个参数值是:http请求头长度+请求尾长度+文件总长度  
    sprintf(temp, "Content-Length: %d

", 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.
");     
             break;     
         }     
         else if (nRet == SOCKET_ERROR)     
         {     
             printf("socket error
");     
             break;     
         }     
         else     
         {     
             printf("recv() returned %d bytes
", nRet);     
             printf("received: %s
", 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
");  
                }  
                catch  
                {  
                    Response.Write("Error
");  
                }  
                Response.End();  
            }  
        }  
    }  
}  

上面就是简单的代码示例,web需配置iis,相信大家知道怎么做^_^,还有一点就是web程序默认上传文件的限制,默认上传大小为4M,所以需要
在web.config中设置以下参数:
[html] view plaincopy
<httpRuntime maxRequestLength="951200" appRequestQueueLimit="60" executionTimeout="60"/>  

这里的maxRequestLength即是默认的上传文件大小,单位是KB。

原文地址:https://www.cnblogs.com/hzcya1995/p/13318430.html