C# 使用TcpClient模拟HTTP请求的使用

一般做http模拟请求的一般使用HttpWebRequest这种方式,但这种方式也存在着一些bug,因为HttpWebRequest是使用的Windows系统定制的net通信,xp跟win7他们有的地方就不一样,HttpWebRequest可以说是给Windows定制的模拟操作,如果遇见某些服务器,可能根本不吃这一套,就像我最近遇到的问题,设置的Content-Length竟然可能视为无效,但正常访问抓包ok,程序跑起来有一半多时候会出错,还有其他的一些问题,比如设置了进制自动重定向,如果再设置Expect100Continue时候,前面的设置会发生无效,无奈,尝试使用TcpClient方式解决了。当下载文件时候,HttpWebRequest好像根据操作系统有最大文件的限制,所以这个时候使用TcpClient也是不错的选择

下面是我下好的一个类,我使用已经够了,可能中间有不足,希望大家指出

  1 class HTTPClass
  2     {
  3 
  4         public Response HTTP(string _url, string _type, string _postdata, string _cookie, Encoding _responseEncode)
  5         {
  6 
  7             try
  8             {
  9                 TcpClient clientSocket = new TcpClient();
 10                 Uri URI = new Uri(_url);
 11                 clientSocket.Connect(URI.Host, URI.Port);
 12                 StringBuilder RequestHeaders = new StringBuilder();
 13 
 14                 RequestHeaders.Append(_type + " " + URI.PathAndQuery + " HTTP/1.1\r\n");
 15                 RequestHeaders.Append("Content-Type:application/x-www-form-urlencoded\r\n");
 16                 RequestHeaders.Append("User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11\r\n");
 17                 RequestHeaders.Append("Cookie:" + _cookie + "\r\n");
 18                 RequestHeaders.Append("Accept:*/*\r\n");
 19                 RequestHeaders.Append("Host:" + URI.Host + "\r\n");
 20                 RequestHeaders.Append("Content-Length:" + _postdata.Length + "\r\n");
 21                 RequestHeaders.Append("Connection:close\r\n\r\n");
 22 
 23                 byte[] request = Encoding.UTF8.GetBytes(RequestHeaders.ToString() + _postdata);
 24                 clientSocket.Client.Send(request);
 25 
 26                 byte[] responseByte = new byte[1024000];
 27                 int len = clientSocket.Client.Receive(responseByte);
 28                 string result = Encoding.UTF8.GetString(responseByte, 0, len);
 29                 clientSocket.Close();
 30                 int headerIndex = result.IndexOf("\r\n\r\n");
 31                 string[] headerStr = result.Substring(0, headerIndex).Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
 32                 Dictionary responseHeader = new Dictionary();
 33                 for (int i = 0; i < headerStr.Length; i++)
 34                 {
 35                     string[] temp = headerStr[i].Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries);
 36                     if (temp.Length == 2)
 37                     {
 38                         if (responseHeader.ContainsKey(temp[0]))
 39                         {
 40                             responseHeader[temp[0]] = temp[1];
 41                         }
 42                         else
 43                         {
 44                             responseHeader.Add(temp[0], temp[1]);
 45                         }
 46                     }
 47                 }
 48                 Response response = new Response();
 49                 response.HTTPResponseHeader = responseHeader;
 50                 string[] httpstatus = headerStr[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
 51                 if (httpstatus.Length > 2)
 52                 {
 53 
 54                     response.HTTPStatusCode = httpstatus[1];
 55                 }
 56                 else
 57                 {
 58 
 59                     response.HTTPStatusCode = "400";
 60                 }
 61                 response.HTTPResponseText = _responseEncode.GetString(Encoding.UTF8.GetBytes(result.Substring(headerIndex + 4)));
 62                 return response;
 63 
 64             }
 65             catch
 66             {
 67                 return null;
 68             }
 69 
 70         }
 71 
 72 
 73     }
 74 
 75     class Response
 76     {
 77 
 78         string hTTPStatusCode;
 79         /// 
 80 
 81         /// http状态代码
 82         /// 
 83 
 84         public string HTTPStatusCode
 85         {
 86             get { return hTTPStatusCode; }
 87             set { hTTPStatusCode = value; }
 88         }
 89         Dictionary hTTPResponseHeader;
 90         /// 
 91 
 92         /// Response的header
 93         /// 
 94 
 95         public Dictionary HTTPResponseHeader
 96         {
 97             get { return hTTPResponseHeader; }
 98             set { hTTPResponseHeader = value; }
 99         }
100         string hTTPResponseText;
101         /// 
102 
103         /// html代码
104         /// 
105 
106         public string HTTPResponseText
107         {
108             get { return hTTPResponseText; }
109             set { hTTPResponseText = value; }
110         }
111 
112 
113     }
View Code

只给大家做参考使用,具体情况具体分析

以上程序对对于来获取一个小网页完全可以,但如果你网页比较大的话,就会出现接收不全的问题,这个问题主要是因为服务器那边响应请求的时候,首先把要响应的内容写如缓冲区,然后根据本身的设定一次次发送内容,而我这只是接受了一次,所以当文本过大时候,就会只接收一部分,如果你的内容过大,可以循环接收下来解决这个问题,当然,可能你有更好的方法

转载:http://www.lyblog.info/archives/955

posted on 2013-10-18 12:26  星辰灬静丨  阅读(1269)  评论(0)    收藏  举报

导航