0x00 起

最近在做一个对时间要求比较高的扫描器,需要封装一下SOCKET模拟HTTP发包的一些常用函数。简单的说,就是重写一下requests中的get、post方法。

今天在写的时候,遇到一枚很奇怪的问题,对同一个URL,POST请求能正常返回信息,而一旦切到GET,socket time out。

伪代码如下:

get_str = 'GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36\r\nAccept: */*\r\n\r\n'
post_str = 'POST %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36\r\n\r\n%s\r\n\r\n' def get(url,port):
sock = socket.connect(url,port)
sock.send(get_str % (url, port)) response = ''
temp = sock.recv(4096)
while temp:
temp = sock.recv(4096)
response += temp return response

0x10 结

心烦意乱的调了很久无果,出去吃了个饭,回来查查资料,从头开始顺了一遍,找到了bug点。原因是HTTP 1.1协议中,默认connection: keep-alive。

Connection: keep-alive   当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接

Connection: close  代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。

而python中的sock.recv如果接收不到数据,会等到TCP连接down掉,才会返回NULL。如果在程序中没有设置超时时间,会等到服务器主动断开连接,一般是30s~60s。

这就是造成socket timeout的原因。在http request里添加connection: close即可解决问题。但是为什么只有get受到影响,post却没有问题呢?

做了个简单的测试:

post 很快就返回了结果:

而get用了很久才返回结果,其中connection为keep-alive:

所以,之前所说的HTTP 1.1协议中,所有的请求都默认为Connection: keep-alive是错误的认识。

只有get请求会默认采取Connection: keep-alive

参考资料:

https://www.byvoid.com/blog/http-keep-alive-header

Python socket模拟HTTP请求的更多相关文章

  1. Socket模拟HTTP请求

    WEB服务器可以可以理解为socket的上层封装,其也是TCP/IP协议,只要知道其IP地址和端口号就可以与他进行通信了 与WEB服务器数据交互,其重点在于请求头,如果请求头不对则不能进行数据传输 简 ...

  2. socket 模拟 HTTP请求

    一.socket介绍 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层.socket则是对TCP/I ...

  3. PHP+SOCKET 模拟HTTP请求

    HTTP消息结构 客户端请求包括四部份:请求行(状态行).请求头.空行.请求主体(数据),如下图: 服务端响应包括四部份:响应行(状态行).响应头.空行.响应主体(数据),如图: HTTP请求方法: ...

  4. python socket 模拟tcp通讯

    对于tcp server 端的创建而言, 分为如下步骤:   1,创建socket对象(socket):其中俩个参数分别为     Address Family(如AF_INET为ipv4),AF_I ...

  5. Java Socket 模拟HTTP请求

    public static void main(String[] args) { try { String url = "192.168.1.103"; Socket socket ...

  6. PHP socket模拟POST请求

    <?php if (! function_exists ( 'socket_post' )) { function socket_post($url, $data, $referer = '') ...

  7. 第九章:Python高级编程-Python socket编程

    第九章:Python高级编程-Python socket编程 Python3高级核心技术97讲 笔记 9.1 弄懂HTTP.Socket.TCP这几个概念 Socket为我们封装好了协议 9.2 cl ...

  8. gj10 python socket编程

    10.1 HTTP.Socket.TCP这几个概念 五层网络模型 socket 不属于任何协议,是一个API,通过socket 可以和传输层的打交道,然后在之上可以实现自己的功能和协议 10.2 cl ...

  9. 第五十九节,模拟浏览器请求Python结合html基本格式

    模拟浏览器请求Python结合html基本格式 用Python模拟一个客户端,结合打开一个HTML页面 创建客户端 #!/usr/bin/env python # -*- coding:utf8 -* ...

随机推荐

  1. ConcurrentHashMap和Hashtable区别

    Hashtable:synchronized是针对整张Hash表的,即每次锁住整张表让线程独占安全的背后是巨大的浪费 ConcurrentHashMap和Hashtable主要区别就是围绕着锁的粒度以 ...

  2. 解决TestNG报java.net.SocketException

    在运行TestNG时一直给我提示报“java.net.ScketException”问题, 网上查了下这个问题是要有网络写入的一些操作才会导致,我的程序也没有网络写入,因为我是使用的selenium+ ...

  3. 是时候全面使用html5标签了

    html5,这个词语,不管是业内还是业外,都已经耳熟能详了.因为已经火了这么长的的时间了.但是,真正开始使用的又有多少人呢?只能用呵呵来形容了! html5真的来了 2014年10月28日,历经八年, ...

  4. ubuntu(16.04.01)学习-day2--高级命令

    1.查找命令 find -name "hello.c" grep "test" grep "usb" -c -r /drivers/usb ...

  5. Contoso 大学 - 4 - 创建更加复杂的数据模型

    原文 Contoso 大学 - 4 - 创建更加复杂的数据模型 原文地址:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using- ...

  6. iOS - 视图与手势(UIview & UIGestureRecognizer)

    01 UIView视图的基本使用 --- 在根视图中添加2个UIView视图 //视图确实加载时调用 - (void)viewDidLoad { [super viewDidLoad]; // Do ...

  7. Swift调用Objective-C

    Swift调用Objective-C需要一个名为“<工程名>-Bridging-Header.h”的桥接头文件,如下图所示.桥接头文件的作用是为Swift调用Objective-C对象搭建 ...

  8. 从0开始学习react(三)

    这次我们来讲解第三节知识,考虑了下,先不去讲什么理论了,毕竟网上一搜一大堆,而且理论真心看不太懂啊!!! 今天我们就直接上实例喽! 大家HIGH起来!!!(想了好久,还是没舍得删这句话) 1.根据下图 ...

  9. javascript笔记—— 构造函数

    出处:http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html 数据类型 ...

  10. dorado问题查询&快捷键重命名

    重命名还有一个快捷键  F2 有关dorado的问题可以进 www.bsdn.org提问,而且更好