【Python 基础】网络编程 - Python写一个简单的HTTP服务端和客户端,实现Client/Server交互

1.HTTP

首先讲一下http和https,详细可以去看runoob http-vs-https

基本概念

HTTP(HyperText Transfer Protocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。

HTTP默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。

HTTP
协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

HTTPS 默认工作在 TCP 协议443端口,它的工作流程一般如以下方式:

1、TCP 三次同步握手 2、客户端验证服务器数字证书 3、DH 算法协商对称加密算法的密钥、hash 算法的密钥 4、SSL
安全加密隧道协商完成
5、网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改。

截至 2018 年 6 月,Alexa 排名前 100 万的网站中有 34.6% 使用 HTTPS 作为默认值,互联网 141387
个最受欢迎网站的 43.1% 具有安全实施的 HTTPS,以及 45% 的页面加载(透过Firefox纪录)使用HTTPS。2017 年3
月,中国注册域名总数的 0.11%使用 HTTPS。

根据 Mozilla 统计,自 2017 年 1 月以来,超过一半的网站流量被加密。

HTTP 与 HTTPS 区别

HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。

socket

2.Python http

具体可以参考:http — HTTP 模块

http 是一个包,它收集了多个用于处理超文本传输协议的模块:

  • http.client 是一个低层级的 HTTP 协议客户端;对于高层级的 URL 访问请使用 urllib.request

  • http.server 包含基于 socketserver 的基本 HTTP 服务类

  • http.cookies 包含一些有用来实现通过 cookies 进行状态管理的工具

  • http.cookiejar 提供了 cookies 的持久化

http 也是一个通过 http.HTTPStatus 枚举定义了一些 HTTP 状态码以及相关联消息的模块

class http.HTTPStatus

3.源码实例

server.py
#coding=utf-8
import http.client
import urllib
from http.server import HTTPServer, BaseHTTPRequestHandler
import json

def start_server():
    data = {'result': 'this is a test'}
    host = ('localhost', 8981)

    class Resquest(BaseHTTPRequestHandler):
        def do_GET(self):
            data={"Method:":self.command,
                  "Path:":self.path}
            print(data)
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())

        def do_POST(self):
            length = int(self.headers['Content-Length'])
            post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8'))
            # You now have a dictionary of the post data
            data = {"Method:": self.command,
                    "Path:": self.path,
                    "Post Data":post_data}
            print(data)
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())

        def do_HEAD(self):
            data = {"Method:": self.command,
                    "Path:": self.path,
                    "Header Content-type": self.headers.get('Content-type')}
            print(data)
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()

            self.wfile.write(json.dumps(data).encode())
        def do_PUT(self):
            data = {"Method:": self.command,
                    "Path:": self.path,
                    "Header Content-type": self.headers.get('Content-type')}
            print(data)
            path = self.path
            content_length = int(self.headers.get('content-length'))
            content = self.rfile.read(content_length)
            #safe_mkdir(os.path.dirname(path))
            with open("D:/code/pyhttp/put_datas.txt", 'ab') as outfile:
                outfile.write(content)
            self.send_response(200)
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())
    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: %s:%s" % host)
    server.serve_forever()

if __name__ == '__main__':
    start_server()
    print("start server success...")
client.py
#coding=utf-8
import http.client
from urllib import request, parse


def send_get(url,path,data):
    conn = http.client.HTTPConnection(url)
    conn.request("GET", path)
    r1 = conn.getresponse()
    print(r1.status, r1.reason)

    data1 = r1.read()
    print(data1)  #
    conn.close()

def send_post(url,path,data,header):
    conn = http.client.HTTPConnection(url)
    conn.request("POST", path,data,header)
    r1 = conn.getresponse()
    print(r1.status, r1.reason)

    data1 = r1.read()
    print(data1)  #
    conn.close()
def send_head(url,path,data,header):
    conn = http.client.HTTPConnection(url)
    conn.request("HEAD", path,data,header)
    r1 = conn.getresponse()
    print(r1.status, r1.reason)
    data1 = r1.headers  #
    print(data1)  #
    conn.close()
def send_put(url,path,filedata,header):
    conn = http.client.HTTPConnection(url)
    conn.request("PUT", path,filedata,header)
    r1 = conn.getresponse()
    print(r1.status, r1.reason)

    data1 = r1.read()  #
    print(data1)
    conn.close()

if __name__ == '__main__':

    url="localhost:8981"
    data = {
        'my post data': 'I am client , hello world',
    }
    datas = parse.urlencode(data).encode('utf-8')

    headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
    print("----------Send get test:-----------")
    send_get(url,path="/index",data="None")
    print("----------Send post test:-----------")
    send_post(url, path="/index",data=datas,header=headers)
    print("----------Send head test:-----------")
    send_head(url, path="/index", data=datas, header=headers)

    print("----------Send put test:-----------")
    tfile=open("test.txt",encoding="utf-8",mode='r')
    filedatas=tfile.read()
    fileheaders = {"Content-type": "text/plain", "Accept": "text/plain",\
                   "content-length":str(len(filedatas))}
    send_put(url, path="/index", filedata=filedatas, header=fileheaders)

效果:
在这里插入图片描述
在这里插入图片描述

4.完整代码下载

https://download.csdn.net/download/Datapad/19119843

### 回答1: 为了在局域网内创建服务端客户端,您可以使用 Python 的 socket 模块。下面是一个简单的例子: 服务端代码: ``` import socket # Create a socket object s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind the socket to a specific address and port s.bind(('127.0.0.1', 6000)) # Listen for incoming connections s.listen(1) print('Server is listening...') # Accept an incoming connection conn, addr = s.accept() print('Connection from:', addr) # Send a message to the client conn.sendall(b'Welcome to the server!') # Close the connection conn.close() ``` 客户端代码: ``` import socket # Create a socket object s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect to the server s.connect(('127.0.0.1', 6000)) # Receive a message from the server print(s.recv(1024)) # Close the connection s.close() ``` 若需要添加UI界面,可以使用pyqt,tkinter等框架编,具体可以参考文档。 后台面板使用js,就需要前后端分离,后台使用python提供api,然后前端用js调用. ### 回答2: 用Python局域网内的服务端客户端,并拥有UI界面,使用JS编后台面板是可行的。 要实现这个功能,可以使用Python的socket模块来实现服务端客户端之间的通信。首先需要创建一个服务端程序,通过绑定本地IP地址和指定端口号来监听客户端的连接请求。当有客户端连接成功后,服务端可以与客户端进行数据交互服务端需要使用多线程或多进程来实现同时处理多个客户端的连接请求,以便同时为多个客户端提供服务。可以使用Python内置的threading或multiprocessing模块来实现多线程或多进程的支持。 在服务端的UI界面方面,可以使用Python的GUI库来实现,例如Tkinter、PyQt等。可以将服务端的界面设计成一个图形化的程序,包括一些按钮、输入框和输出框等,以便与客户端进行交互。 在后台面板方面,可以使用HTML、CSS和JS来设计一个Web页面,通过JavaScript与服务端进行通信。可以使用JavaScript的XMLHttpRequest或WebSocket等技术与服务端进行数据交互,通过AJAX实现实时更新和动态显示。 通过这样的实现,可以在局域网内建立起一个服务端与多个客户端之间的通信系统,并通过UI界面和后台面板来方便地进行交互和管理。 ### 回答3: 用Python一个在局域网内的服务端客户端是可行的,可以使用Python内置的socket库来实现网络通信功能。 首先,我们可以创建一个服务端程序,代码如下: ```python import socket # 创建socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置IP地址和端口号 host = '0.0.0.0' port = 12345 # 绑定IP地址和端口号 server_socket.bind((host, port)) # 监听请求 server_socket.listen(1) # 等待客户端连接 client_socket, client_address = server_socket.accept() # 接收客户端发送的数据 data = client_socket.recv(1024).decode() print('收到客户端消息:', data) # 发送响应给客户端 response = 'Hello, client!' client_socket.send(response.encode()) # 关闭连接 client_socket.close() server_socket.close() ``` 运行以上代码,服务端将监听在IP地址为'0.0.0.0',端口号为12345的地址上,并等待客户端的连接。一旦有客户端连接上来,服务端会接收客户端发送的数据,并发送响应给客户端。 接下来,我们可以创建一个客户端程序,代码如下: ```python import socket # 创建socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置IP地址和端口号 host = '服务端IP地址' port = 12345 # 连接服务端 client_socket.connect((host, port)) # 发送数据给服务端 data = 'Hello, server!' client_socket.send(data.encode()) # 接收服务端响应的数据 response = client_socket.recv(1024).decode() print('收到服务端消息:', response) # 关闭连接 client_socket.close() ``` 在客户端代码中,将"服务端IP地址"修改为实际的服务端IP地址。运行以上代码,客户端会连接到服务端,并发送数据给服务端,然后接收服务端响应的数据。 要实现具有UI界面的程序,可以使用Python的GUI库Tkinter来创建图形界面。而要使用JavaScript编后台面板,可以使用Python的web框架如Django或Flask来搭建一个简单的web服务器,然后使用JavaScript与服务端进行通信。 最后,使用Tkinter创建的图形界面和使用JavaScript编的后台面板可以在同一个Python程序中共存,同时运行。这样,你就可以拥有一个在局域网内的带有UI界面,并且可以通过后台面板进行控制的服务端客户端了。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AiFool

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值