XX学Python·网络

TCP客服端程序开发

(Transmission Control Protocol)传输控制协议

  1. 导入socket模块
  2. 创建TCP套接字‘socket’
  • 参数1: ‘AF_INET’, 表示IPv4地址类型
  • 参数2: ‘SOCK_STREAM’, 表示TCP传输协议类型
  1. 发送数据‘send’
  • 参数1: 要发送的二进制数据, 注意: 字符串需使用encode()方法进行编码
  1. 接收数据‘recv’
  • 参数1: 表示每次接收数据的大小,单位是字节
  1. 关闭套接字‘socket’表示通信完成
import socket
# 1、创建socke对象
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 2、连接服务器
client.connect(('192.168.14.26', 8005))
# 3、发送数据
# 将字符串转为bytes类型 data.encode()或b'hello'直接按照bytes类型传递数据
while True:  # 循环发送和接收数据
    data = 'hello'  # 若是中文,需指定gbk或utf-8
    client.send(data.encode('gbk'))
    # 4、接受服务端返回数据 recv(1024)需指定接受数据大小
    # 将bytes类型转为字符串 recv_data.decode()
    recv_data = client.recv(1024)
    str_data = recv_data.decode('gbk')
    print(str_data)
# 5、关闭客户端
client.close()

TCP服务端程序开发

  1. 导入socket模块
  2. 创建TCP套接字‘socket’
  • 参数1: ‘AF_INET’, 表示IPv4地址类型
  • 参数2: ‘SOCK_STREAM’, 表示TCP传输协议类型
  1. 绑定端口号‘bind’
  • 参数: 元组, 比如:(ip地址, 端口号)
  1. 设置监听‘listen’
  • 参数: 最大等待建立连接的个数
  1. 等待接受客户端的连接请求‘accept’
  2. 发送数据‘send’
  • 参数: 要发送的二进制数据, 注意: 字符串需要使用encode()方法进行编码
  1. 接收数据‘recv’
  • 参数: 表示每次接收数据大小,单位是字节,注意: 解码成字符串使用decode()方法
  1. 关闭套接字‘socket’表示通信完成
# 导入网络开发工具
import socket
import threading


# 封装处理客户端数据的方法
def client_data(clinet_sockt):
    while True:
        # 5、接受客户端传递的数据
        recv_data = clinet_sockt.recv(1024)
        # 6、返回数据给客户端
        data = 'hello client'
        clinet_sockt.send(data.encode())


# 1、创建服务端连接对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、绑定ip和端口,方便后续监听是否有客户端请求服务端的ip和端口
server.bind(('192.168.14.26', 8005))
# 3、指定监听的数量
server.listen(5)
print('服务端启动......')
# 让服务端持续接收客户端请求的数据
while True:
    # 4、等待客户端连接
    clinet_sockt, addr = server.accept()
    print('客户端socket', clinet_sockt)
    print('客户端地址', addr)
    # 创建线程处理每一个客户端的请求数据
    t = threading.Thread(target=client_data, args=(clinet_sockt,))
    t.start()
# 7、关闭服务端
server.close()

HTTP协议和静态Web服务器

  • HTTP (HyperText Transfer Protocol)超文本传输协议

    • HTTP协议是基于TCP传输协议传输数据的

    • HTTP协议规定了浏览器和 Web 服务器通信数据的格式

  • URL(Uniform Resoure Locator)统一资源定位符,通俗说是网络资源地址,即常说的网址。

    • URL组成部分

      1. 协议部分
      2. 域名部分
      3. 资源路径部分
      4. 查询参数部分 [可选]
  • 开发者工具是查看http协议的通信过程利器,通过Network标签选项可以查看每一次的请求和响应的通信过程,调出开发者工具的通用方法是在网页右击选择检查。

    • 开发者工具的Headers选项总共有三部分组成:
      1. General: 主要信息
      2. Response Headers: 响应头
      3. Request Headers: 请求头
    • Response选项是查看响应体信息的
  • HTTP请求报文:客服端给服务端发送数据时需要遵循的数据格式

    由请求行、请求头、和请求体组成。每项数据间用:\r\n换行

    • 请求行由三部分组成:GET / HTTP/1.1
      1. 请求方式:GET获取web服务器数据,还有POST向web服务器提交数据
      2. 请求资源路径
      3. HTTP协议版本
    • 请求头:格式key:value,键值对间也用\r\n换行
    • 请求体:一般携带文件数据(图片,音视频,普通文本),json数据,表单数据
  • HTTP响应报文:服务端给客服端发送数据时需要遵循的数据格式

    由响应行、响应头、和响应体组成。

    • 响应行由三部分组成:HTTP协议版本,状态码,状态描述,最常见状态码是200

    • 响应头:key:value,如服务器名称server:taobao,一般返回服务器名称,其他默认

    • 响应体:一般携带文件数据(图片,音视频,普通文本),json数据

  • python自带静态服务使用

    • 1、创建前端文件 new>>HTML File

    • 2、操作浏览器操作复制其他网站页面,粘贴进刚创建的文件里

    • 3、启动python自带的静态服务器,在终端(terminal)界面操作

      • 注意:一定要在前端文件所在的目录下进行启动,端口号不指定默认8000

        python3 -m http.server 8080若系统只有一个python3版本,则不需加上3

    • 4、查看本机ip地址,取浏览器访问HTML File文件,如 192.168.88.8:8080

  • 静态Web服务器,面向对象的静态服务器

import socket
import threading
class WebServer():

    def __init__(self):
        # 1、创建服务端对象
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 2、绑定ip和端口
        self.server.bind(('192.168.14.56', 8001))
        # 3、监听
        self.server.listen(5)

    def clinet_request(self,clinet_data):
        # 接受客户端(浏览器)数据
        recv_data = clinet_data.recv(1024)
        # 解决方案一 提前判断数据是为空
        # if len(recv_data) == 0:
        #     clinet_data.send('not data')
        # 解决方案二,捕获数据处理异常,捕获到异常就结束函数的业务逻辑执行
        try:
            # 读取请求报文中的请求路径,根据不同的请求路径返回不同的页面
            # 1、将bytes类型转为字符串
            str_data = recv_data.decode()
            # 2、字符串切割 按照\r\n进行切割  得到请求行、请求头数据、请求体数据   GET /register HTTP/1.1\r\nHost: 127.0.0.1:8009\r\nConnection: keep-alive\r\n
            data_list = str_data.split('\r\n')
            # 3、从切割后的列表中提取请求行数据 ,再次按照空格切割请求行数   GET /register HTTP/1.1
            request_line = data_list[0]
            # 4、从切割后的请求行列表数据中提取请求路径
            url_path = request_line.split(' ')[1]
        except Exception as e:
            # 输出异常信息
            print(e)
            clinet_data.send(b'not data')
            return None
        # 5、根据不同的请求路径读取不同的页面文件数据返回浏览器
        if url_path == '/':
            # 请求首页
            # 读取首页文件返回给浏览器
            f = open('./index.html', 'r', encoding='utf-8')
            send_data = f.read()
            f.close()
        elif url_path == '/register':
            # 注册页面
            # 读取注册页面数据
            f = open('./register.html', 'r', encoding='utf-8')
            send_data = f.read()
            f.close()
        else:
            f = open('./404.html', 'r', encoding='utf-8')
            send_data = f.read()
            f.close()

        # 构建报文数据
        # 响应行
        response_line = 'HTTP/1.1 200 ok\r\n'
        # 响应头
        response_header = 'Server:itcast\r\n\r\n'
        # 响应体
        response_body = send_data

        respose_data = response_line + response_header + response_body

        clinet_data.send(respose_data.encode())

    def start(self):

        # 循环等待客户端连接
        print('服务器启动。。。')
        while True:
            clinet_data, addr = self.server.accept()
            print('请求的客户端:', clinet_data)
            # 创建线程处理客户端请求
            t = threading.Thread(target=self.clinet_request, args=(clinet_data,))
            # 启动线程
            t.start()

web = WebServer()
web.start()
posted @ 2022-10-04 23:04  PORTB  阅读(21)  评论(0编辑  收藏  举报