咱们学习网络编程最相熟的莫过于 Http,好,咱们就从 Http 动手,首先咱们必定要理解一下 http 的基本原理和作为,对 http 的工作原理有肯定水平的把握,对咱们上面的学习都是有很大帮忙的。
一:工作形式
①:client 和 server 建设牢靠的 TCP 连贯。
②:而后 client 通过 Socket 向 server 发送 http 申请。
③:server 端解决申请,返回解决数据。
④:在 http1.0 中,client 与 server 之间的 tcp 连贯立刻断开。
但在 http1.1 中,因为默认反对“tcp 的长连贯”,所以 server 端采纳超时才断开 tcp 连贯的策略。
二:特点
①:Http 是无状态的,这个置信大家都晓得,我就不多说了。
②:client 通过在 Http 申请中的 Header 里追加一些信息来通知 Server 传送的主体的相干信息,比方:主体是什么类型,什么编码。
三:Http 申请和响应探索
置信大家都晓得罕用的申请形式也就是 ”Get” 和“Post”,那么上面就来探索下 Get 和 Post 都有哪些好玩的中央,还是上图谈话,首先
我输出 www.baidu.com,会找到如下的申请和响应的信息。
1:“Request Header“:
第一行:Get / Http/1.1
这外面有三个信息:①”Get”, 示意申请的模式。②“/”,申请网站的根目录。③”http/1.1″,这个就是 http 的版本。
第二行:Host
申请指标的网站,跟“/” 并一起就是 ”www.baidu.com/”。
第三行:Connection
默认为“keep-Alive“,这里就是文章结尾所说的默认反对长连贯。
第四行:Cache-Control
这玩意跟缓存无关,其中 max-age 示意缓存的工夫(s)。
第五行:User-Agent
通知 serve 我 client 的身份,个别由浏览器决定,比方:浏览器类型,版本等等。
第六行:Accept
以及前面的 Accept 打头的都是表明 client 可能接管的品种和类型。
最初一行:Cookie
如果咱们第一次向 baidu 申请时是没有 cookie 信息这一栏的,因为在浏览器下找不到于 baidu 相干的 cookie,
当咱们第二次刷新页面时,get 申请就会找到本地的 cookie 并附带给 server。
2: “Response Header”:
第一行:Http/1.1 200 OK
这个预计大家都晓得吧,200 示意返回的状态码,OK 则是描述性的状态码。
第二行:Date
示意服务器响应的工夫。
第三行: Server
响应客户端的服务器。
第四行:Content-Length
示意服务器返回给客户端注释的字节流长度。
第五行:Content-Type
示意注释的类型。
第七行:Expires
通知 client 相对的过期工夫,比方 2012.1.10, 在这个工夫内 client 都能够不必发送申请而间接从 client 的 cache 中获取,
对 js,css,image 的缓存很有益处,所以说用好了这个属性对咱们 http 的性能有很大的帮忙。
第八行:Content-Encoding
文档类型的编码方式,服务器端采纳 gzip 的模式进行了文档压缩,此时减小了文档,利于下载,然而必须 client 端反对
gzip 的解码操作。
post 的形式也是一样的,这里就不说了,下面列举了这么多也是心愿大家可能对 Http 的细节要有肯定水平的把握。
四:利用场景
咱们在 http 下面的网络编程个别次要做两件事件。
①:爬数据,模仿登录,主动填表单。
②:文件的上传和下载。
不过.net 对 Http 进行了十分好的封装,提供了 HttpWebRequest 和 HttpWebResponse 来给咱们提供罕用操作,如果大家对 Http 协定有个比拟清晰的意识我想类库外面的属性和办法都是神马和浮云。
五:案例
第一步:首先咱们写两个 action,一个 login(登录页面),一个 index(用户后盾首页)。
1 namespace Test.Controllers
2 {3 [HandleError]
4 public class HomeController : Controller
5 {6 public ActionResult Login()
7 {8 return View();
9 }
10
11 [HttpPost]
12 public ActionResult Index(Model model)
13 {14 if (model.UserName == "11" && model.Password == "11")
15 return View(model);
16 else
17 return RedirectToAction("Login");
18 }
19
20 public ActionResult About()
21 {22 return View();
23 }
24 }
25
26 public class Model
27 {28 public string UserName { get; set;}
29
30 public string Password {get; set;}
31 }
32 }
好了,咱们关上 fiddler,输出 admin,admin,点击提交,看看都 post 些什么到 server 端了,不便咱们前面的模仿登录,这里的 head 信息置信大家还是能看懂吧。
第二步:咱们新建一个 winform 的程序。
1 namespace Http
2 {
3 public partial class Form1 : Form
4 {5 public Form1()
6 {7 InitializeComponent();
8 }
9
10 private void Form1_Load(object sender, EventArgs e)
11 {
12 // 网页内容填充 webbrowser1 控件
13 string url = "http://localhost:59773/";
14
15 // 创立 http 链接
16 var request = (HttpWebRequest)WebRequest.Create(url);
17
18 var response = (HttpWebResponse)request.GetResponse();
19
20 Stream stream = response.GetResponseStream();
21
22 StreamReader sr = new StreamReader(stream);
23
24 string content = sr.ReadToEnd();
25
26 webBrowser1.DocumentText = content;
27 }
28
29 /// <summary>
30 /// 暴力破解
31 /// </summary>
32 /// <param name="sender"></param>
33 /// <param name="e"></param>
34 private void button1_Click(object sender, EventArgs e)
35 {
36 var url = "http://localhost:59773/Home/Index";
37
38 // 上一次的返回后果
39 string prev = string.Empty;
40
41 for (int i = 0; i < 100; i++)
42 {43 var username = new Random(DateTime.Now.Millisecond).Next(8, 19).ToString();
44
45 Thread.Sleep(2);
46
47 var password = new Random(DateTime.Now.Millisecond).Next(8, 19).ToString();
48
49 //post 提交的内容
50 var content = "username=" + username + "&password=" + password;
51
52 // 将 content 变为字节模式
53 var bytes = Encoding.UTF8.GetBytes(content);
54
55 var request = (HttpWebRequest)WebRequest.Create(url);
56
57 // 依据 fiddler 中查看到的提交信息,咱们也试着模仿追加此类信息而后提交
58 request.Method = WebRequestMethods.Http.Post;
59 request.Timeout = 1000 * 60;
60 request.AllowAutoRedirect = true;
61 request.ContentLength = bytes.Length;
62 request.ContentType = "application/x-www-form-urlencoded";
63
64
65 // 将 content 写入 post 申请中
66 var stream = request.GetRequestStream();
67 stream.Write(bytes, 0, bytes.Length);
68 stream.Close();
69
70 // 写入胜利,获取申请流
71 var response = (HttpWebResponse)request.GetResponse();
72
73 var sr = new StreamReader(response.GetResponseStream());
74
75 var next = sr.ReadToEnd();
76
77 if (string.IsNullOrEmpty(prev))
78 {
79 prev = next;
80 }
81 else
82 {83 if (prev != next)
84 {
85 webBrowser2.DocumentText = next;
86 MessageBox.Show("祝贺你,明码曾经破解!一共破费:" + (i + 1) + "次,用户名为:" + username + ", 明码为:" + password);
87 return;
88 }
89 }
90
91 }
92 webBrowser2.DocumentText = "不好意思,未能破解";
93 }
94 }
95 }
第三步:咱们当初要做的就是点击”暴力破解”,看看能不能给我枚举进去“肉鸡网站”的用户名和明码。
事实中远不止这么简略,次要还是想让大家可能对 HttpWebReqeust 和 HttpWebResponse 有个理解。