`
小码哥BASE64
  • 浏览: 124579 次
社区版块
存档分类
最新评论

利用socket模拟http的混合表单上传(在一个请求中提交表单并上传多个文件)

阅读更多

 

在很多企业级应用中,我们都没法直接通过开发语言sdk包封装的http工具来模拟http复合表单(multipart/form-data),特别是在跨语言跨平台的编程过程中,其实实现方案并不复杂,只要你了解了http协议中复合表单的报文结构就很简单了:

        httpheader

        ------时间戳------

        表单参数1

       ------时间戳------

       表单参数2

      ------时间戳------

      文件1的描述+二进制信息

     ------时间戳------

     文件2的描述+二进制信息

 

    下面我们进一步以一段c#的代实例码来演示下这个结构:

       

        ///<summary>

        ///向服务器发送混合型的请求,1:成功发送,0:发送失败

        ///</summary>

        ///<param name="paranames">表单参数名数组</param>

        ///<param name="paravalues">参数值数组</param>

        ///<param name="files">文件名数组</param>

        ///<param name="errmsg">报错信息</param>

        ///<returns></returns>

        public int SendRequest(string[] paranames, string[] paravalues, string[] files, ref string errmsg)

        {

            StringBuilder http, text;

            byte[] httpbyte;

            byte[] textbyte = null;

            long length = 0;

            DateTime now = DateTime.Now;

            List<byte[]> data =new List<byte[]>();

            //构造时间戳

            string strBoundary = "------------" + DateTime.Now.Ticks.ToString("x");

            byte[] boundary = Encoding.ASCII.GetBytes("\r\n" + strBoundary +"\r\n");

            length += boundary.Length;

            //构造时间戳

 

            //加载表单参数信息

            if (paranames != null)

            {

                text = new StringBuilder();

                for (int i = 0; i < paranames.Length; i++)

                {

                    text.Append("--");

                    text.Append(strBoundary);//添加时间戳

                    text.Append("\r\n");

                    text.Append("Content-Disposition: form-data; name=\"" + paranames[i] +"\"\r\n\r\n");

                    text.Append(paravalues[i]);

                    text.Append("\r\n");

                }

                string para = text.ToString();

                textbyte = Encoding.ASCII.GetBytes(para);

                length += textbyte.Length;

            }

 

            //加载文件信息

            if (files != null)

            {

                for (int i = 0; i < files.Length; i++)

                {

                    FileStream fs;

                    StringBuilder sbfile =new StringBuilder();

                    try

                    {

                        fs = File.Open(files[i],FileMode.Open, FileAccess.Read,FileShare.Read);

                        if (i == 0) sbfile.Append("--");//添加文件

                        else sbfile.Append("\r\n--");

                        sbfile.Append(strBoundary);//添加时间戳                       

                        sbfile.Append("\r\n");

                        sbfile.Append("Content-Disposition: form-data; name=\"");

                        sbfile.Append("file");

                        sbfile.Append("\"; filename=\"");

                        sbfile.Append(Path.GetFileName(files[i]));

                        sbfile.Append("\"");

                        sbfile.Append("\r\n");

                        sbfile.Append("Content-Type: ");

                        sbfile.Append("application/octet-stream");

                        sbfile.Append("\r\nContent-Length:");

                        sbfile.Append(fs.Length.ToString());

                        sbfile.Append("\r\n");

                        sbfile.Append("\r\n");

                        string temp = sbfile.ToString();

                        byte[] bin =Encoding.UTF8.GetBytes(temp);

                        data.Add(bin);

                        length += bin.Length;

                        length += fs.Length;

                        fs.Close();

                    }

                    catch (Exception exc)

                    {

                        errmsg = exc.Message.ToString();

                        return 0;

                    }

 

                }

            }

 

            //构造http

            http = new StringBuilder();

            http.Append("POST " + ur.ToString() +" HTTP/1.1\r\n");

            http.Append("Content-Type:multipart/form-data;boundary=");

            http.Append(strBoundary);

            http.Append("\r\n");

            http.Append("Host:" + ipaddress +":" + tcpport.ToString() + "\r\n");

            http.Append("Content-Length:");

            http.Append(length.ToString());

            http.Append("\r\n");

            http.Append("Expect: 100-continue\r\n");//注明要在收到服务器的continue消息后才继续上传http消息体

            http.Append("Connection: Keep-Alive\r\n\r\n");

            string strtemp = http.ToString();

            httpbyte = Encoding.ASCII.GetBytes(strtemp);

 

            try

            {

                soc.Send(httpbyte);"//首先发送http头            

               Thread.Sleep(100);

                string check = GetResponse();

                if (check == null || !check.Contains("Continue"))//得到服务器确认后才继续上传

                {

                    errmsg = "客户端已成功发送请求,但服务器没有响应!";

                    return 0;

                }

                if (paranames != null)

                {

                    soc.Send(textbyte, textbyte.Length, SocketFlags.None);//发送表单参数

                }

                if (files != null)

                {//依次发送文件

                    for (int i = 0; i < data.Count; i++)

                    {

                        int size = 0;

                        FileStream fs =File.Open(files[i], FileMode.Open, FileAccess.Read, FileShare.Read);

                        soc.Send(data[i], data[i].Length, SocketFlags.None);

                        byte[] buff =new byte[1024];

                        size = fs.Read(buff, 0, 1024);

                        while (size > 0)

                        {

                            soc.Send(buff, size, SocketFlags.None);

                            size = fs.Read(buff, 0, 1024);

                        }

                        fs.Close();

                    }

                }

                soc.Send(boundary, boundary.Length, SocketFlags.None);

                return 1;

            }

            catch (Exception exc)

            {

                errmsg = exc.Message.ToString();

                return 0;

            }

        }

分享到:
评论

相关推荐

    JAVA SOCKET模拟HTTP请求,文件上传!

    采用JAVA的socket实现http协议,模拟浏览器访问服务端。

    Android下socket模拟http server

    在Android平台上,我们可以利用Socket编程来模拟一个简单的HTTP服务器,以提供本地文件系统中的资源,如HTML文件,供外部设备(如浏览器)访问。这个过程涉及到Android系统的网络权限管理、Socket编程以及HTTP协议的...

    socket文件上传代码

    1. **建立连接**:客户端(文件上传者)创建一个Socket对象,并使用服务器的IP地址和端口号发起连接请求。服务器端监听特定端口,当收到连接请求时,会创建一个Socket与客户端建立连接。 2. **数据封装**:在Java中...

    【最新】C++ 通过socket tcp实现http post form_data表单提交图片, mp4到http服务器

    在IT领域,网络编程是不可或缺的一部分,特别是在C++这样的系统级编程语言中。本文将深入讲解如何使用C++通过socket TCP实现...而`socket_client`这个文件可能就是这样一个客户端示例代码,可以作为学习和参考的对象。

    JAVA Socket编程实现文件上传

    在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库中。这个过程涉及到多个关键知识点,下面我们将详细探讨。 1. **Java Socket基础**:...

    socket http/https 模拟登录 请求页面等

    在文件名“WebCrawler”中,我们可以推测这是一个关于网络爬虫的项目。网络爬虫是一种自动浏览和抓取网页的程序,它通常会利用HTTP/HTTPS请求模拟登录到网站,以便抓取需要的数据。在实现过程中,socket可以用于创建...

    c#使用Socket发送HTTP/HTTPS请求的实现代码

    在提供的代码中,sendsRequestRetry方法是一个核心方法,该方法使用Socket发送HTTP/HTTPS请求,并对请求的结果进行处理。该方法主要完成了以下几个步骤: 1. 创建一个Socket对象,并连接到目标服务器。 2. 发送...

    使用Socket 完成HTTP post方式的文本及文件上传 demo

    在网络中,一个Socket可以理解为一个通信端点,它包含IP地址和端口号,这两个元素共同定义了网络上的唯一位置。而HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从万维网服务器传输超文本到本地...

    一个使用C语言socket发送http请求的例子

    这是一个linux下使用C的标准socket,进行http访问的例子。通过socket发送get请求,从中国天气网获得指定城市的天气。 该例子在ubuntu 14.04和AM3358的嵌入式linux3.14下实际测试可用。 如果需要在嵌入式linux下使用...

    Socket实现文件上传下载,含多线程

    在本示例中,"Socket实现文件上传下载,含多线程" 提到了通过Socket在客户端和服务器之间进行文件传输,并且服务器端采用了多线程处理连接请求,提高了服务的并发能力。下面我们将详细探讨相关的知识点。 1. **...

    socket 文件上传下载

    在本文中,我们将深入探讨如何使用Socket进行文件的上传和下载操作,这对于网络应用程序的开发至关重要,特别是涉及到数据传输的应用,如云存储、文件共享等。 首先,我们需要理解Socket的基本概念。Socket是一种...

    android中基于socket方式的文件上传

    总的来说,实现Android中基于Socket方式的文件上传是一个涉及网络编程、文件操作和异常处理等多个方面的综合任务。通过不断学习和实践,开发者可以熟练掌握这一技术,为用户提供更加稳定和高效的文件上传体验。

    c语言编写 基于SOCKET HTTP Json 请求

    1. **初始化SOCKET**:使用`WSAStartup`函数初始化Winsock,然后创建一个SOCKET对象,通过`socket`函数指定协议类型(如TCP/IP)。 2. **连接服务器**:使用`gethostbyname`或`getaddrinfo`获取服务器的IP地址和...

    C代码版本的HTTP POST上传文件/JSON

    3. **文件上传**:在HTTP POST请求中上传文件,需要将文件内容编码成二进制流,并在Content-Type头中指定`multipart/form-data`。每个文件都应包含一个边界标识符,以区分不同的文件或字段。 4. **JSON数据**:JSON...

    Socket模拟服务器_Socket模拟服务器_

    要创建一个Socket模拟服务器,首先我们需要创建一个ServerSocket实例,并指定一个端口号。例如: ```java ServerSocket serverSocket = new ServerSocket(8888); ``` 这里的8888是服务器监听的端口号,必须确保该...

    安卓Android源码——Android中Socket大文件断点上传.zip

    - **分块传输**:将大文件拆分成多个小块,每次只上传一个块,这样可以减少因网络问题导致的重传范围。 - **服务器状态存储**:服务器端保存每个文件块的状态,如是否已接收、接收的顺序等。 4. **Android源码...

    socket实现文件上传下载

    当客户端通过发送 `connect` 请求与服务器端建立 Socket 连接后,客户端会向服务器发送一个文件。服务器接收这个文件,并将其保存到指定目录下。完成文件上传后,服务器主动断开连接。 ##### 2. 服务器端实现代码...

    python利用socket上传文件的客户端和服务器代码

    在这个场景下,我们将探讨如何使用Python的socket库来实现文件的上传功能。这个过程涉及到两个主要部分:客户端(Client)和服务器端(Server)。客户端将本地文件发送到服务器,而服务器端接收并保存这些文件。 ...

    FTPUtil.vb 利用Socket 实现FTP文件上传和文件下载

    FTPUtil.vb是一个VB.NET编写的实用工具,它利用Socket编程接口实现了FTP(File Transfer Protocol)文件上传和下载的功能。FTP是一种广泛应用于互联网上的协议,主要用于在客户端与服务器之间进行文件传输。Socket是...

    socket实现上传文件工具类

    本篇文章将详细探讨如何利用Socket实现一个强大的文件上传工具类,以及涉及到的相关知识点。 一、Socket基础知识 Socket,也被称为套接字,是网络通信中的一个抽象概念,它代表了两台机器间通信的一个端点。在Java...

Global site tag (gtag.js) - Google Analytics