本文转自:http://www.rupeng.com/forum/thread-16020-1-1.html
最近因为某些需要,在学习如何通过编程来和Web服务器交互。
现在似乎有点入门了,和大家分享一下心得。
(估计这也是做农场外挂等的基础,如果你有兴趣,欢迎和我讨论)
1.前期准备
必备知识/工具:
1.http协议基础
2.网络抓包工具
要与web服务器进行交互,基本的http协议知识是必须的。
这里我用自己的理解来简单说下吧:
初学时,需要知道http协议最重要的几个特点,否者就无法正确编写程序。
1.http协议是请求/应答模式的
就是,首先你先发一个请求给web服务器,然后web服务器会给你一个回应。
与web服务器的交互过程,就是这“一问一答”的过程。
常用请求有2种,一种是Get(用于请求获取资源)。一种是Post(用于请求提交表单等数据)
2.http协议是不维持连接的。
这个是什么意思呢?和我们上次做的foxmail的smtp协议不同,
http协议在每一次的“问答”过程结束后,服务器都会关闭连接。
就是说,你soket创建一个套接字去连接服务器,并且发送了一个请求(问),
服务器返回一个请求的结果(答)后,服务器就会关闭这个套接字。
如果要在发送第二个请求怎么办?——再创建一个套接字,再去连接服务器。
3.http协议不会记录访问者的状态
如2所说,http协议不维持连接。每一次问答结束后,连接的套接字就没用了。
那么,像论坛这样的网站是如何记住我们已经登录了呢?答案是:cookies.
在提交登录表单后,如果登录成功,服务器会返回一个或几个cookie。
在下一次的请求中,再次把这些cookie发送给服务器,来证明自己已经登录了网站。
以上3点,是我这几天学习的总结,如有错,还请高手指点。
有了http的基础知识后,我们还需要一款网络抓包工具,
去了解浏览器在与web服务器交互的过程中都发送/接收到了什么。
我们自己编写的程序,其实也就是把浏览器发给服务器的东西自己再发送一次
浏览器发送了什么,我们就发送什么,从而达到模拟浏览器与服务器交互的过程。
抓包工具有很多:Ethereal , sniffer 都可以。
这里我们只关心http的数据,所以选用:HttpWatch.
关于HttpWatch的详细使用,你们自己百度下吧。。。这里我就不罗嗦了
2.我编写的HttpTester工具
这个“工具”很简单,是用来发送一些测试的http请求数据的,并且接收服务器的回应数据。
如果想做个论坛自动灌水机,或者是什么XX网页游戏的助手的话。可以先用HttpTester来测试一下。
HttpTester界面如下:
我的HttpTester可执行文件下载:
HttpTester.rar(135.99
KB, 下载次数: 633)
HttpTester源代码:
IDE:VS2005
语言:C++
接收数据的延迟,是发送请求后,等待多久才去接收服务器的回应。
为什么要等待呢?如果不等待,请求发送过去后(用send函数),
马上去接收数据(调用recv函数),用非阻塞的套接字会收不到任何数据(原因是明显的)。
就算用了阻塞的套接字,也可能会只收到了“半截”数据。因为服务器如果发送大量的回应数据
网络延迟的存在,我们主机可能会先收到一部分数据,而其他部分的数据在延迟了几秒后才到达。
阻塞套接字的recv接收,在收到一部分数据后,就返回了。
用非阻塞的套接字是什么情况呢?
可以先调用select函数来延迟几秒,测试是否有数据达到。有数据达到了,再调用recv去接收。
注意:select函数的行为是:一旦在指定的延迟时间内,发现能读取数据后,它就返回。
就是说,当只有半截数据过来时,select也返回了,这时调用recv还是只接收到了半截数据。
用简单的方法,阻塞和非阻塞套接字都不能很好地完全接收数据。
我的做法是:先用Sleep函数延迟几秒,然后select函数判断一下,是否有能读取的数据。
如果有,就调用recv去接收。由于事先调用了select判断,
我觉得这里用阻塞的,非阻塞的套接字都无关紧要。
我的这个做法,还有缺陷,就是延迟时间不够的话,还是不能完全接收服务器的回应数据。
回想http协议的特点,服务器会在回应完毕后,关闭套接字。
我们可以尝试做一个recv接收数据循环。循环终止的条件是:套接字已被服务器closesocket掉了。
这个尝试,就交给你们来完成了,谁有做这个测试的,得出结果后,请通知我。。。
我的简单处理方法,已能应付大多数情况。嘿嘿。
3.HttpWatch+HttpTester与服务器交互。
3.1取得CSDN注册会员页面的验证码图片
我先举这个例子来说明,其他的应该可以触类旁通了。
CSDN注册会员的页面地址是:http://passport.csdn.net/UserLogin.aspx?from=%2fPassport.aspx
我们要取得这个页面上的这张验证码图片:
1.打开HttpWatch来分析浏览器在取这张验证码时发送了怎样的请求。
我们可以看到浏览器在请求这张图片时,发送了如下数据:
GET /ShowExPwd.aspx?temp=ge6nmewq HTTP/1.1
Accept: */*
Referer: http://passport.csdn.net/UserLogin.aspx?from=%2fPassport.aspx
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: passport.csdn.net
Connection: Keep-Alive
Cookie: ASP.NET_SessionId=na0bcr0ukuehaamjvzbskgta; ClientKey=ab5eb6b5-94b6-45a5-99fb-1662df04030a
2.打开HttpTest,把这串数据原封不动地复制到“请求的数据”编辑框中。
如下图:
注意:填写“请求的数据”,末尾必须要有2个空行。否则收不到任何回应。
“服务器地址”编辑框填写web服务器的IP或者域名,这里是:passport.csdn.net
“服务器端口”编辑框填写web主机的端口,http协议默认端口是80,这里我们填写默认的端口号:80
“接收数据的延迟”编辑框,设置为:1000(一秒)
然后,就可以点“发送”按钮了。
服务器回应结果如下图:
输入一个文件名,然后点“保存数据”按钮,就会把服务器返回的图片数据保存为文件。
然后点“打开文件”,就可以浏览到收到的验证码图片了。
3.2获取咱如鹏网首页的logo图片。
通过HttpWatch的分析,我们知道浏览器在获取咱如鹏网logo时
是发送了类似如下的请求:
GET /forum/templates/uchome/images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.rupeng.com/forum/
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Host: www.rupeng.com
Connec