2011-04-22 122 views
14

我希望能够构建原始HTTP请求并使用套接字发送它。很显然,你会希望我使用类似urllib和urllib2的东西,但我不想使用它。使用套接字创建原始HTTP请求

它必须是这个样子:

import socket 

tcpsoc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
tcpsoc.bind(('72.14.192.58', 80)) #bind to googles ip 
tcpsoc.send('HTTP REQUEST') 
response = tcpsoc.recv() 

很明显,你也必须要求页/文件和get和post参数

+3

原则上来说,这很容易,你发送'GET someurl HTTP/1.1',接着是'Host:theserversname',然后是两个换行符。让它变得复杂的是,你必须解析一百万个选项和一百万个可能的答案(这就是为什么用户会说“使用一个库”)。 – Damon 2011-04-22 12:47:36

+3

您需要tcpsoc.connect而不是绑定。绑定是用于侦听套接字... – Milan 2011-04-22 12:51:47

+1

这里有一个连接的例子:http://docs.python.org/library/socket.html#example – Milan 2011-04-22 12:52:45

回答

12

大多数时候,你需要知道的是在HTTP/1.1规范,而如果你想推出自己的HTTP实现你一定要学什么:http://www.w3.org/Protocols/rfc2616/rfc2616.html

+7

RFC规则! (在这两个词的意思......) – 2011-04-22 13:28:29

6

是的,基本上你只需要输入文字,例如:

GET /pageyouwant.html HTTP/1.1[CRLF] 
Host: google.com[CRLF] 
Connection: close[CRLF] 
User-Agent: MyAwesomeUserAgent/1.0.0[CRLF] 
Accept-Encoding: gzip[CRLF] 
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF] 
Cache-Control: no-cache[CRLF] 
[CRLF] 

随意随意删除/添加标题。

+0

嗨!什么是以上文本的名称?原始请求,原始消息或其他? – hasanghaforian 2015-02-09 16:23:57

+0

@hasanghaforian - 如果仍然相关,全文称为* HTTP头*。可选地,它后面是真正的内容,由一个空行分隔。当您向客户端发送上传数据到服务器的响应时,就是这种情况。 – linusg 2016-12-06 14:54:40

+0

@linusg谢谢您的回复! – hasanghaforian 2016-12-06 15:10:21

0

对于工作的例子来指导你,你可能想看看在libcurl,图书馆用C语言:

  1. 你想要做什么等等;

  2. 是一个快速使用;

  3. 被广泛部署;和

  4. 被积极支持。

这是一个美丽的东西,也是开源可以和应该是什么的最好例子之一。

23
#!/usr/bin/python 

import socket 
import urlparse 
import re 
import os 

socket.setdefaulttimeout = 0.50 
os.environ['no_proxy'] = '127.0.0.1,localhost' 
linkRegex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?>') 
CRLF = "\r\n\r\n" 


def GET(url): 
    url = urlparse.urlparse(url) 
    path = url.path 
    if path == "": 
     path = "/" 
    HOST = url.netloc # The remote host 
    PORT = 80   # The same port as used by the server 
    # create an INET, STREAMing socket 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    """ 
    *********************************************************************************** 
    * Note that the connect() operation is subject to the timeout setting, 
    * and in general it is recommended to call settimeout() before calling connect() 
    * or pass a timeout parameter to create_connection(). 
    * The system network stack may return a connection timeout error of its own 
    * regardless of any Python socket timeout setting. 
    *********************************************************************************** 
    """ 
    s.settimeout(0.30) 
    """ 
    ************************************************************************************** 
    * Avoid socket.error: [Errno 98] Address already in use exception 
    * The SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state, 
    * without waiting for its natural timeout to expire. 
    ************************************************************************************** 
    """ 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    #s.setblocking(0) 
    s.connect((HOST, PORT)) 
    s.send("GET/HTTP/1.0%s" % (CRLF)) 
    data = (s.recv(1000000)) 
    print data 
    # https://docs.python.org/2/howto/sockets.html#disconnecting 
    s.shutdown(1) 
    s.close() 
    print 'Received', repr(data) 

GET('http://www.google.com') 
+1

我需要修改这个。 – 2017-11-12 19:27:02