使用C#访问百度指数:模拟发送请求/得到响应数据(2) (8月份已过时)

前面我们已经分析了发送给服务器的数据,下面就是我们怎样把这些数据post到服务器了,我们看到对AMF的二进制数据处理(序列化及反序列化)很麻烦,有兴趣的朋友可以使

用FluroineFx
FluroineFx官方网站:http://www.fluorinefx.com/    
FluroineFx下载地址:http://www.fluorinefx.com/download.html
FluroineFx在线文档:http://www.fluorinefx.com/docs/fluorine/index.html

但由于我们的应用非常简单,所以使用网上流传的一个模拟AMF Post的类,做了些修改,主要是我们现在

应用的编码为UTF8

 

class AMFPostData
{
public List<byte> Message; 

/// <summary>初始化Message</summary>       
public AMFPostData(AMFType amftype, int headers, int bodies) 

//AMF版本    
if (amftype == AMFType.AMF0) 

Message = new List<byte>(new byte[] { 0x00, 0x00 }); 

else if (amftype == AMFType.AMF3) 

Message = new List<byte>(new byte[] { 0x00, 0x03 }); 

//header数量    
Message.Add(BitConverter.GetBytes(headers)[1]); 
Message.Add(BitConverter.GetBytes(headers)[0]); 
//body数量    
Message.Add(BitConverter.GetBytes(bodies)[1]); 
Message.Add(BitConverter.GetBytes(bodies)[0]); 


/// <summary>添加Target</summary>      
public void AddTargetAndResponse(string target, string response) 

//添加Target长度    
Message.Add(BitConverter.GetBytes(target.Length)[1]); 
Message.Add(BitConverter.GetBytes(target.Length)[0]); 
//添加Target内容    
Message.AddRange(Encoding.UTF8.GetBytes(target)); 
//添加Response长度    
Message.Add(BitConverter.GetBytes(response.Length)[1]); 
Message.Add(BitConverter.GetBytes(response.Length)[0]); 
//添加Response内容    
Message.AddRange(Encoding.UTF8.GetBytes(response)); 


/// <summary>添加Body</summary>    
/// <param name="length"></param>    
/// <param name="Content"></param>    
public void AddBody(AMFPostDataBody amfpostdatabody) 

Message.AddRange(amfpostdatabody.GetLength()); 
Message.AddRange(amfpostdatabody.Content.ToArray()); 



class AMFPostDataBody 

private byte[] length = new byte[4]; 
public List<byte> Content = new List<byte>(); 

/// <summary>初始化Body</summary>    
public AMFPostDataBody(DataType datatype, int arraylength) 

//添加类型标识    
Content.Add((byte)datatype); 

//数组的话添加长度    
if (datatype == DataType.Array) 

Content.Add(BitConverter.GetBytes(arraylength)[3]); 
Content.Add(BitConverter.GetBytes(arraylength)[2]); 
Content.Add(BitConverter.GetBytes(arraylength)[1]); 
Content.Add(BitConverter.GetBytes(arraylength)[0]); 



public void AddData(DataType datatype, string value) 

//添加类型标识    
Content.Add((byte)datatype); 
switch (datatype) 

case DataType.Number: 
AddData(double.Parse(value)); 
break; 
case DataType.String: 
AddData(value); 
break; 
case DataType.Boolean: 
AddData(Boolean.Parse(value)); 
break; 



#region 各种类型处理方法 
/// <summary>Boolean</summary>       
private void AddData(bool flag) 

if (flag) 
Content.Add(0x01); 
else 
Content.Add(0x00); 

/// <summary>String</summary>      
private void AddData(string value) 

//添加长度    
Content.Add(BitConverter.GetBytes(Encoding.UTF8.GetBytes(value).Length)[1]); 
Content.Add(BitConverter.GetBytes(Encoding.UTF8.GetBytes(value).Length)[0]); 
//添加内容    
Content.AddRange(Encoding.UTF8.GetBytes(value)); 

/// <summary>Number</summary>        
private void AddData(double number) 

byte[] b = new byte[8]; 
b = BitConverter.GetBytes(number); 
for (int i = 7; i > -1; i--) 

Content.Add(b[i]); 


#endregion 

public byte[] GetLength() 

length[0] = BitConverter.GetBytes(Content.Count)[3]; 
length[1] = BitConverter.GetBytes(Content.Count)[2]; 
length[2] = BitConverter.GetBytes(Content.Count)[1]; 
length[3] = BitConverter.GetBytes(Content.Count)[0]; 

return length; 



public enum AMFType 

AMF0, 
AMF3 


public enum DataType 

Number = 0, 
Boolean = 1, 
String = 2, 
UntypedObject = 3, 
MovieClip = 4, 
Null = 5, 
Undefined = 6, 
ReferencedObject = 7, 
MixedArray = 8, 
End = 9, 
Array = 10,//0x0A    
Date = 11,//0x0B    
LongString = 12,//0x0C    
TypeAsObject = 13,//0x0D    
Recordset = 14,//0x0E    
Xml = 15,//0x0F    
TypedObject = 16,//0x10    
AMF3data = 17//0x11    

根据前文分析结果,我们生成数据的方法如下

public static byte[] GetData(string key, string startdate, string enddate)
{
AMFPostData amfpostdata = new AMFPostData(AMFType.AMF3, 0, 1);
amfpostdata.AddTargetAndResponse("DataAccessor.getIndexes", "/1");

AMFPostDataBody amfpostdatabody = new AMFPostDataBody(DataType.Array, 5);
amfpostdatabody.AddData(DataType.String, key);
amfpostdatabody.AddData(DataType.String, "0");
amfpostdatabody.AddData(DataType.String, "");
amfpostdatabody.AddData(DataType.String, "3e263816946471096c");
amfpostdatabody.AddData(DataType.String, "032512b3ee00d43d7f4fb2151b24d35109d8402579");

amfpostdata.AddBody(amfpostdatabody);

byte[] data = amfpostdata.Message.ToArray();

return data;
}


可以使用以下方法发送数据及得到返回响应的二进制数据

public static byte[] GetFlashData(string gateway, byte[] data) 

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(gateway); 
request.Method = "Post"; 
request.ContentType = "application/x-amf"; 
CookieContainer cookie = new CookieContainer(); 
request.CookieContainer = cookie; 

byte[] requestData = data; 
request.ContentLength = requestData.Length; 

byte[] responseData = null; 

try 

using (Stream requestStream = request.GetRequestStream()) 

requestStream.Write(requestData, 0, requestData.Length); 


HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
using (Stream responseStream = response.GetResponseStream()) 

//StreamToBytes是将流转换为二进制字节数组的方法,下文补上 
responseData = StreamToBytes(responseStream); 


catch (Exception ex) 

Console.WriteLine(DateTime.Now.ToString() + "," + ex.Message); 
//Log.WriteLine(DateTime.Now.ToString() + "," + ex.Message); 

return responseData; 
}

你可能感兴趣的:(exception,Stream,String,C#,百度,byte)