• 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。

  • 相关阅读:
    视图中使用select a.* 更改了表a的结构 导致读取字段值时发生错位
    sql 压缩文件(rar或zip)
    单击触发jquery.autocomplete的两种方法
    CSS布局时容易出的小错误,导致浏览器不兼容或者各种不显示
    使用备份数据库.bal文件还原正在使用的数据库
    sql outer join
    利用GBK双字节编码突破PHP单引号转义限制进行SQL注入:set names gbk导致的sql注入
    对可操作对象的占用状态、锁定状态、解锁状态的一些方案
    回车转换成Tab
    DataGrid超级连接列
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318430.html
Copyright © 2020-2023  润新知