与web服务器的GET及POST方法通信

Socket 网络通信简介

Socket 是电脑网络中进程间数据流的端点,也是传输层网络通信的 API。HTTP 作为一个应用层的协议,一般是基于传输层的 TCP 协议的。因此我们要在 TCP 协议上构建我们的程序,也就是使用 Socket 传输 HTTP 的消息。如果你对 Socket 网络编程比较熟悉,可以直接跳过这一节。端口、IP 之类的基本概念就不重复了。下边这张图展示了 Socket TCP 通信的步骤:

  1. 服务器需要新建一个 socket 对象,并将这个对象绑定在某个特定的端口。socket.AF_INET 代表 IPV4 协议族,socket.SOCK_STREAM 代表是 TCP 协议。下一行的 setsockopt 表示这个地址可以重复使用。
  2. 设置这个 socket 对某个特定的端口进行监听,参数代表等待队列的大小。
  3. 调用 accept 方法,等待客户端连接到这个端口上。需要注意的是调用了 accept 方法以后当前进程会阻塞在 accept 函数上,直到收到一个新的连接请求。
  4. 客户端新建 socket 对象。调用 connect 方法去访问特定的地址+端口号。此时当前进程会阻塞在这个位置,直到建立连接。connect 和 accept 建立连接的这个过程,就对应着 TCP 的三次握手过程。
  5. 一旦连接建立,就可以使用 send 和 recv 互相之间发送消息了。recv 的参数代表接收多少个字节。
  6. 当通讯结束的时候需要使用 close 关闭 socket。

这个过程大家可以打开两个 shell,一个做为客户端,一个做为服务器端。注意体会一下阻塞的过程,注意 accept 是什么时候返回的。如下图所示:

-c

Python Socket实现的简单http服务器

#!/usr/bin/env python
#coding=utf-8

import socket
import re

HOST = ''
PORT = 8000

#Read index.html, put into HTTP response data
index_content = '''
HTTP/1.x 200 ok
Content-Type: text/html

'''

file = open('index.html', 'r')
index_content += file.read()
file.close()

#Read reg.html, put into HTTP response data
reg_content = '''
HTTP/1.x 200 ok
Content-Type: text/html

'''

file = open('reg.html', 'r')
reg_content += file.read()
file.close()

#Read picture, put into HTTP response data
file = open('T-mac.jpg', 'rb')
pic_content = '''
HTTP/1.x 200 ok
Content-Type: image/jpg

'''
pic_content += file.read()
file.close()



#Configure socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(100)

#infinite loop
while True:
    # maximum number of requests waiting
    conn, addr = sock.accept()
    request = conn.recv(1024)
    method = request.split(' ')[0]
    src  = request.split(' ')[1]

    print 'Connect by: ', addr
    print 'Request is:\n', request

    #deal wiht GET method
    if method == 'GET':
        if src == '/index.html':
            content = index_content
        elif src == '/T-mac.jpg':
            content = pic_content
        elif src == '/reg.html':
            content = reg_content
        elif re.match('^/\?.*$', src):
            entry = src.split('?')[1]      # main content of the request
            content = 'HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'
            content += entry
            content += '<br /><font color="green" size="7">register successs!</p>'
        else:
            continue
#deal with POST method
    elif method == 'POST':
        form = request.split('\r\n')
        entry = form[-1]      # main content of the request
        content = 'HTTP/1.x 200 ok\r\nContent-Type: text/html\r\n\r\n'
        content += entry
        content += '<br /><font color="green" size="7">register successs!</p>'

    ######
    # More operations, such as put the form into database
    # ...
    ######

    else:
        continue

    conn.sendall(content)

    #close connection
    conn.close()

chmod +x httpServer.py, 并运行./httpServer.py

使用浏览器当做客户端访问服务器

httpServer.py 所在目录有index.html, reg.html, T-mac.jpg

-c

get演示

在chrome浏览器中打开http://127.0.0.1:8000/index.html

效果如下

命令行中显示

服务器输出:

Connect by:  ('127.0.0.1', 54234)
Request is:
GET /index.html HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7


Connect by:  ('127.0.0.1', 54235)
Request is:
GET /T-mac.jpg HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8000/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7


Connect by:  ('127.0.0.1', 54236)
Request is:
GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8000/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7

post演示

在chrome浏览器中打开http://127.0.0.1:8000/reg.html

效果如下

-c

命令行中显示

Connect by:  ('127.0.0.1', 54248)
Request is:
GET /reg.html HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7


Connect by:  ('127.0.0.1', 54249)
Request is:
GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8000/index.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7

点击提交数据后

-c

Connect by:  ('127.0.0.1', 54257)
Request is:
POST / HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Content-Length: 55
Cache-Control: max-age=0
Origin: http://127.0.0.1:8000
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1:8000/reg.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7

user=mhj&psw=123&repsw=123&sex=nan&tech=java&country=cn
Connect by:  ('127.0.0.1', 54258)
Request is:
GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8000/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7


Connect by:  ('127.0.0.1', 54259)
Request is:
GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8000/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7

其中user=mhj&psw=123&repsw=123&sex=nan&tech=java&country=cn
就是我刚刚输入的表单数据

如果我们把 表单中的 method 改成get

此时浏览器会访问http://127.0.0.1:8000/?user=mhj&psw=123&repsw=123&sex=nan&tech=java&country=cn

在这里可以总结一下post 跟 get 提交的一些区别:

get提交,提交的信息都显示在地址栏中;对于敏感数据不安全;由于地址栏存储体积有限而不能提交大容量数据;将信息封装到了请求消息的请求行

中,而post 提交将信息封装到了请求体中。

猜你喜欢

转载自blog.csdn.net/qq_31805821/article/details/80834600