2011-04-22 8 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() 

분명히 당신은 또한 페이지/파일을 요청하고 얻을 POST 매개 변수

+3

기본적으로 완전히 쉽습니다. 'GET someurl HTTP/1.1'다음에 'Host : theserversname'다음에 두 개의 개행 문자가옵니다. 복잡하게 만드는 이유는 백만 가지 옵션과 백만 가지 가능한 답글을 파싱해야한다는 것입니다 (즉, "라이브러리 사용"이라고 말하는 것이 좋습니다). – Damon

+3

바인드 대신 tcpsoc.connect가 필요합니다. 바인딩은 청취 소켓을위한 것입니다 ... – Milan

+1

여기에 connect의 예가 나와 있습니다. http://docs.python.org/library/socket.html#example – Milan

답변

12

당신은 당신이 당신의 자신의 HTTP 구현 롤하려는 경우 당신은 확실히 공부해야하는 HTTP/1.1 스펙에 알아야 할 대부분의 : 당신을 안내 할 수있는 작업 예를 들어 http://www.w3.org/Protocols/rfc2616/rfc2616.html

+7

RFC 규칙! (두 단어의 의미로 ...) –

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

+0

@hasanghaforian - 여전히 관련성이있는 경우 전체 텍스트를 * HTTP 헤더 *라고합니다. 선택적으로 실제 내용이 하나의 빈 줄로 구분됩니다. 서버에 업로드 데이터의 응답을 클라이언트에 다시 보낼 때이 경우입니다. – linusg

+0

@linusg 답장을 보내 주셔서 감사합니다! – hasanghaforian

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

이것을 개정해야합니다. –