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

分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

最近项目需要,通过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。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

原文地址:https://www.cnblogs.com/sjwudhwhhw/p/10509757.html

时间: 2024-10-10 02:48:47

vc++ socket http协议post方法上传 分块上传的相关文章

https 协议下服务器根据网络地址下载上传文件问题

https 协议下服务器根据网络地址下载上传文件遇到(PKIX:unable to find valid certification path to requested target 的问题) 使用httpclient  所有站点全部信任 不做身份鉴定: 1 public static CloseableHttpClient getHttpClient() throws Exception { 2 SSLConnectionSocketFactory sslsf = null; 3 Poolin

js方法用来获取路径传参上所带的参数

//js方法用来获取路径传参上所带的参数 function GetQueryString(param) { var reg = new RegExp("(^|&)" + param + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); if (r != null) { return r[2]; } return null;

进程对象的其他方法、守护进程、使用多进程实现 socket tcp协议 server端的并发(抢票程序)、队列、进程之间的通信(IPC)

# 进程对象的其他方法 from multiprocessing import Process import time class MyProcess(Process): def __init__(self, a, b): # 为了给子进程传递参数 super().__init__() self.a = a self.b = b def run(self): print("子进程开始执行") time.sleep(2) print("子进程结束", self.a,

手把手教你玩转SOCKET模型之重叠I/O篇(上)

“身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬.” ----- 题记  By PiggyXP(小猪) 前   言   其实我首先应该道歉,因为7月份的时候曾信誓旦旦的说要写一套关于SOCKET所有模型的入门文章以及配套代码,不过没想到后天竟然被美女所迷出去度假了,刚刚回来不久......-_-b其实那些模型的配套代码我已经基本写完了,

socket上传图片的处理方法

最近在用socket上传数据,无奈传文本没有问题,但是传图片就是有问题.想过了各种方法,客户端传过去,然后,服务器端分包接收.这种方法,没有成功.似乎还有一种方法,就是客户端分包发送,服务器端接收,然后,组合到一起,但是想想,似乎更复杂. 最后终于解决了.就是用HTTP上传图片文件.然后,服务器端返回一个保存图片文件的id.(当然是服务器端保存文件的id).然后,在用socket上传,此时文件已经传过去了.所以,用socket上传的部分就不是那么大了.好了,上传代码. //HTTP协议相关代码

实现HTTP协议Get、Post和文件上传功能——设计和模块

之前写过一遍<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>,其中谈到了如何使用WinHttp接口实现Http的Get.Post和文件上传功能.后来发现蛮多人关注该技术的实现,于是我决定重新设计框架结构,梳理这块的知识并提供可供测试的方案.同时,该系列也将作为<VC开发Windows客户端软件之旅>中"网络"模块的一部分. 本系列不再将技术限定于WinHttp接口,还引入curllib库.同时为了公正且方便测试代码的正确性,我们将引入成熟

VC socket Connect 超时时间设置

设置connect超时很简单,CSDN上也有人提到过使用select,但却没有一个令人满意与完整的答案.偶所讲的也正是select函数,此函数集成在winsock1.1中,简单点讲,"作用使那些想避免在套接字调用过程中被锁定的应用程序,采取一种有序的方式,同时对多个套接字进行管理"(<Windows网络编程技术>原话).使用方法与解释请见<Windows网络编程技术>. 在使用此函数前,需先将socket设置为非阻塞模式,这样,在connect时,才会立马跳过,

实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现

在<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>一文中,我已经比较详细地讲解了如何使用WinHttp接口实现各种协议.在最近的代码梳理中,我觉得Post和文件上传模块可以得到简化,于是几乎重写了这两个功能的代码.因为Get.Post和文件上传功能的基础(父)类基本没有改动,函数调用的流程也基本没有变化,所以本文我将重点讲解修改点.(转载请指明出于breaksoftware的csdn博客) 首先我修改了接口的字符集.之前我都是使用UNICODE作为接口参数类型,其中一个

【纯干货】4年前想解决的事情,今天才实验成功:浏览器原生分块上传文件

第一份软件开发工作的第一个星期(不算做试用期的一个星期,无薪水试用).因为不是软件专业,也没有经过培训和相关工作经验.老板不放心,但还是让我试一试.做的第一件事情就是上传文件,实时看进度,并且上传后预览.预览的文件类型有word,ppt,excel,flash,视频按帧获取预览图.office文件是在服务器端转成html后显示出来. 做的还满意,就留下来了,后来就在那个公司待了两年. 没解决的事情: 上传大文件,分块上传,浏览器原生不支持,需要借助第三方插件.最根本的原因就是浏览器端的js考虑的