Python实现HTTP GET请求

在互联网上,我们可以让某台计算机作为服务器。服务器开放自己的端口,被动等待其他计算机连接。当其他计算机作为客户,主动使用socket连接到服务器的时候,服务器就开始为客户提供服务。

在Python中,我们使用标准库中的socket包来进行底层的socket编程。

首先是服务器端,我们使用bind()方法来赋予socket以固定的地址和端口,并使用listen()方法来被动的监听该端口。当有客户尝试用connect()方法连接的时候,服务器使用accept()接受连接,从而建立一个连接的socket:

# Written by Windy
# Server side
import socket

# Address
HOST = ''
PORT = 8000

reply = 'Yes'

# Configure socket
s      = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))

# passively wait, 3: maximum number of connections in the queue
s.listen(3)
# accept and establish connection
conn, addr = s.accept()
# receive message
request    = conn.recv(1024)


print 'request is: ',request
print 'Connected by', addr
# send message
conn.sendall(reply)
# close connection
conn.close()

socket.socket()创建一个socket对象,并说明socket使用的是IPv4(AF_INET,IP version 4)和TCP协议(SOCK_STREAM)。

然后用另一台电脑作为客户,我们主动使用connect()方法来搜索服务器端的IP地址(在Linux中,你可以用$ifconfig来查询自己的IP地址)和端口,以便客户可以找到服务器,并建立连接:

# Written by Windy
# Client side
import socket

# Address
HOST = '172.20.202.155'
PORT = 8000

request = 'can you hear me?'

# configure socket
s       = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

# send message
s.sendall(request)
# receive message
reply   = s.recv(1024)
print 'reply is: ',reply
# close connection
s.close()

现在,我们写出一个HTTP服务器端:

#coding=utf-8
#Python HTTP服务器端
'''
自己编写一个HTTP服务器端使用socket
'''
#Written by Winy
import socket
import datetime
#Address
HOST=''
PORT=8882
# Prepare HTTP response
today = datetime.datetime.now()
text_content = '''HTTP/1.x 200 OK  
Content-Type: text/html

<head>
<title>WOW</title>
</head>
<html>
<p>Wow, Python Server</p>'''+ datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") +'''
<p>Wow, Python Server</p>
<IMG src="test.jpg"/>
</html>
'''
# Read picture, put into HTTP format
f = open('test.jpg','rb')
pic_content = '''
HTTP/1.x 200 OK  
Content-Type: image/jpg

'''
pic_content = pic_content + f.read()
f.close()
# Configure socket
s    = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
# infinite loop, server forever
while True:
    # 3: maximum number of requests waiting
    s.listen(3)
    conn, addr = s.accept()
    request    = conn.recv(1024)
    print request
    method = request.split(' ')[0]
    src =request.split(' ')[1]

    # deal with GET method
    if method == 'GET':
        # ULR    
        if src == '/test.jpg':
            content = pic_content
        else: content = text_content

        print 'Connected by', addr
        print 'Request is:', request
        conn.sendall(content)
    # close connection
    conn.close()

使用浏览器实验

为了配合上面的服务器程序,我已经在放置Python程序的文件夹里,保存了一个test.jpg图片文件。我们在终端运行上面的Python程序,作为服务器端,再打开一个浏览器作为客户端。(如果有时间,你也完全可以用Python写一个客户端。原理与上面的TCP socket的客户端程序相类似。)

测试#

在浏览器的地址栏输入:

127.0.0.1:8882

文章参考地址