在很多企业级应用中,我们都没法直接通过开发语言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协议,模拟浏览器访问服务端。
这是一个linux下使用C的标准socket,进行http访问的例子。通过socket发送get请求,从中国天气网获得指定城市的天气。 该例子在ubuntu 14.04和AM3358的嵌入式linux3.14下实际测试可用。 如果需要在嵌入式linux下使用...
该代码实现了对于socket发送http请求上传文件的封装,且上传了一个模拟服务端的php代码,在 test目录,首先需要自己下载PHPStudy安装好,然后将下载下来的资源中test目录的文件复制到php目录下www目录中,启动...
socket http/https 模拟登录 请求页面等
这是文件上传的java代码,通过socket上传的,所以可以跨服务器,可公用的
Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-文件上传Socket网络编程-...
利用Socket 实现FTP文件上传和文件下载
这个工具就是一个能在线模拟socket通讯工具,并且能检测通讯是否能正常响应和发送信息
通过socket模拟ftp主动和被动两种模式下上传下载文件,代码完整,直接导入项目就可以调试
网上很多有关socket文件传输的源码都是每次只能发送一个文件,如果想传输多个文件,不但需要多次交互,还需要把每个文件的文件名都输入进去,很不方便,所以进行了一个小扩展:即客户端可以将打算传送的多个文件都先...
编写一个网络服务器的模拟程序: 从一个SOCKET监听网络请求,并进行处理. 网络用户可发来四类请求A/B/C/D/E. 每个类请求分别用一个函数处理. A请求的处理函数是睡眠1秒钟, B请求的处理函数是睡眠2秒钟, C请求的处理...
模拟Socket通讯服务端,实现网络通讯社数据的接收,根据接收数据判断处理
基于java socket发送http请求。这种原生的发送请求的方式能适合一些特定场景,比如: A向B发送请求,A不考虑B是否处理成功,即A不关注B的响应结果,那么A就不用阻塞等B的回应。 传统的Httpclient请求方式都是阻塞...
python利用socket上传文件的客户端和服务器代码。代码比较简短,运行在Python3平台,本人测试过MP3问价和mp4文件,传输的效果很好。
用JAVA实现的文件上传,控制台输入,保存到数据库
安卓Android源码——Android中Socket大文件断点上传.zip
socket实现文件上传下载
在andriod下实现一个间的socket server 安装以后可以通过,浏览器访问/mnt/sdcard/IDATACHINA文件夹下的html文件
socket 文件上传下载 方便大家学习交流
主要介绍了C#基于socket模拟http请求的方法,实例分析了socket模拟http请求的实现技巧,需要的朋友可以参考下