python高级-socket和web相关

news2024/11/16 21:41:08

目录

一、socket

1.客户端开发

2.tcp客户端

3.tcp服务端

4.连接的注意事项

5.多任务服务端

二、静态web

1.请求报文

2.响应头

3.静态web服务器

4.socket静态页面

5.多进程模拟404和200状态码

6.面向对象多任务

结语


一、socket

1.客户端开发

  1. 创建客户端套接字对象
  2. 和服务端套接字建立连接
  3. 发送数据
  4. 接收数据
  5. 关闭客户端套接字
  6. 对应状态

导入socket模块

import socket

创建客户端socket对象

socket.socket(AddressFamily,Type)

参数说明:

AddressFamily表示ip地址类型,分为ipv4和ipv6

Type表示传输协议类型

方法说明

  • connect(host,port)表示和服务端套接字建立连接,host是服务器ip地址,port是应用程序的端口号
  • send(data)表示发送数据,data是二进制数据
  • recv(buffersize)表示接收数据,buffersize是每次接收数据的长度

2.tcp客户端


import socket



if __name__ = 'main':
    #socket.AF_INET:代表ipv4     socket.SOCK_STREAM tcp传输协议
    tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    #服务端192.168.131.62 8000端口建立连接
    tcp_client_socket.connect(('192.168.131.62',8000))
    
    #代码执行到此,说明链接建立成功
    #准备发送的数据
    send_data = "您好服务端,我是客户端的小明".encode("gbk")
    
    #发送数据
    tcp_client_socket.send(send_data)
    
    #接收数据,这次接受的数据最大字节数是1024
    recv_data = tcp_client_socket.recv(1024)
    
    #返回的直接是服务端程序发送的二进制
    print(recv_data)
    
    #解码输出
    recv_content = recv_data.decode("gbk")
    print("接受服务端的数据为:",recv_content)
    
    #关闭套接字
    tcp_client_socket.close()
    

3.tcp服务端


import socket



if __name__ == '__main__':

    #socket.AF_INET:代表ipv4     socket.SOCK_STREAM tcp传输协议
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #设置端口号复用,让程序推出端口号立刻释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)

    #给程序绑定端口号
    tcp_server_socket.bind(("",8989))

    #设置最大等待建立连接的个数,目前是单任务服务端,后续会用多任务
    tcp_server_socket.listen(128)

    #解包
    service_client_socket,ip_port = tcp_server_socket.accept()

    #代码执行到此说明连接建立成功
    print("ip和port: ",ip_port)

    #接受客户端发送的数据,这次接受数据的最大字节数是(1024)
    recv_data = service_client_socket.recv(1024)

    recv_data_len = len(recv_data)
    print("接受客户端的数据的长度为:",recv_data_len)
    print("接受客户端的数据为:",recv_data)

    #解码
    rev_de_data = recv_data.decode("gbk")
    print("解码后的客户端数据: ",rev_de_data)

    #关闭套接字
    tcp_server_socket.close()


4.连接的注意事项

  • 当tcp客户端程序想和tcp服务端程序进行通信的时候必须要先建立连接
  • tcp客户端程序一般不一定需要绑定端口号,因为客户端时主动发起连接的
  • TCP服务端程序必须绑定端口号,否则客户端找不到这个tcp服务端程序
  • listen后的套接字时被动套接字,只负责接收新的客户端连接请求,不能收发消息。
  • 当TCP客户端程序和TCP服务端程序连接成功后,TCP服务端程序会产生一个新的套接字,收发客户端使用该套接字
  • 关闭accept返回的套接字意味着和这个客户端已经通信完毕。
  • 关闭listen后的套接字意味着服务端的套接字已经关闭了,会导致新的客户端不能连接服务端,但之前已经连接成功的客户端还能正常通信。
  • 当客户端的套接字调用close后,服务端的recv会解阻塞,返回的数据长度为0,服务端可以通过返回数据的长度来判断客户端是否已经下线,反之服务端关闭套接字,客户端的recv也会阻塞,返回的数据长度为0。

5.多任务服务端

  • 编写一个tcp服务端程序,循环等待接受客户端的连接请求
  • 当客户端和服务端建立连接成功,创捷子线程,使用子线程专门处理客户端的请求,防止主线程阻塞
  • 把创建的子线程设置为守护主线程,防止主线程无法退出
import socket
import threading

def handle_client_r(service_client_socket,ip_port):
    #单客户端内部循环检测
    while True:
        #循环接受客户端发送的数据
        #接受客户端发送的数据
        recv_d = service_client_socket.recv(1024)

        #容器类型判断是否有数据可以直接使用if语句进行判断,如果容器类型里面有数据表示条件成立
        #容器类型:列表、字典、元组、字符串、set、range、二进制数组
        if recv_d:
            print(recv_d.decode("gbk"),ip_port)

            #回复
            service_client_socket.send("你好我是服务端。。。。".encode("gbk"))
        else:
            print("客户端下线了: ",ip_port)
            break

    service_client_socket.close()
if __name__ == '__main__':
    #创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #设置端口号复用,让程序推出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)

    #绑定端口号
    tcp_server_socket.bind(("",9090))

    #设置监听,listen后的套接字是被动套接字,只负责接收客户端的连接请求
    tcp_server_socket.listen(128)
    
    #多客户端socket
    while True:
        #等待接收客户端的连接请求
        service_client_s,ip_port = tcp_server_socket.accept()
        print("客户端连接成功: ",ip_port)

        #当客户端和服务端建立连接成功后,需要创建一个子线程,不同子线程负责接受不同客户端的消息
        sub_t = threading.Thread(target=handle_client_r,args=(service_client_s,ip_port))

        #设置守护主线程
        sub_t.setDaemon(True)

        #启动子线程
        sub_t.start()

import socket
import threading

class SocketServer(object):
    def __init__(self):
        # 创建tcp服务端套接字
        self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 设置端口号复用,让程序推出端口号立即释放
        self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

        # 绑定端口号
        self.tcp_server_socket.bind(("",6666))

        # 设置监听,listen后的套接字是被动套接字,只负责接收客户端的连接请求
        self.tcp_server_socket.listen(128)

    def start(self):
        #多客户端socket
        while True:
            #等待接收客户端的连接请求
            service_client_s,ip_port = self.tcp_server_socket.accept()
            print("客户端连接成功: ",ip_port)

            #当客户端和服务端建立连接成功后,需要创建一个子线程,不同子线程负责接受不同客户端的消息
            sub_t = threading.Thread(target=self.client_t,args=(service_client_s,ip_port))

            #设置守护主线程
            sub_t.setDaemon(True)

            #启动子线程
            sub_t.start()

        self.tcp_server_socket.close()

    def client_t(self,service_client_socket,ip_port):
        print(ip_port,"  连接上来了")
        #单客户端内部循环检测
        while True:
            #循环接受客户端发送的数据
            #接受客户端发送的数据
            recv_d = service_client_socket.recv(1024).decode('gbk')

            #容器类型判断是否有数据可以直接使用if语句进行判断,如果容器类型里面有数据表示条件成立
            #容器类型:列表、字典、元组、字符串、set、range、二进制数组
            if len(recv_d) != 0:
                print(f'客户端{ip_port[0]} 发来的消息是{recv_d}')
            else:
                print(f'客户端{ip_port[0]} 已断开连接,下次再见。。。。')
                break
            send_data = ('Hello 我是服务端 --'+recv_d).encode('gbk')
            service_client_socket.send(send_data)

if __name__ == '__main__':
    server = SocketServer()
    server.start()


二、静态web

1.请求报文

2.响应头

响应码

3.静态web服务器

python3 -m http.server

http://127.0.0.1:8000/index1.html

http://0.0.0.0:8000/

4.socket静态页面


import socket



if __name__ == '__main__':
    #创建tcp服务端套接字
    tcp_serv_s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #设置端口号复用
    tcp_serv_s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)

    #端口绑定
    tcp_serv_s.bind(("",9000))

    #设置监听
    tcp_serv_s.listen(128)

    while True:
        #等待接受客户端的连接请求
        new_socket,ip_port = tcp_serv_s.accept()

        #代码执行到此,说明连接建立成功
        recv_c_d = new_socket.recv(4096)

        #对接收的客户端的请求包头进行二进制解码
        recv_c_con = recv_c_d.decode("utf-8")
        print(recv_c_con)

        with open("./index1.html",'rb') as f:
            f_d = f.read()

        #相应行
        response_l = "HTTP/1.1 200 OK\r\n"

        #响应头
        response_h = "Server: PWS1.0\r\n"

        #响应体
        response_b = f_d

        #拼接响应报文
        res_d = (response_l+response_h+"\r\n").encode("utf-8") + response_b

        #发送数据
        new_socket.send(res_d)

new_socket.close()

5.多进程模拟404和200状态码

import multiprocessing
import socket


def serv_start(port):
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
    server.bind(("",port))
    server.listen(128)

    while True:
        client,ip_port = server.accept()
        print(f"客户端{ip_port[0]} 使用{ip_port[1]} 端口连接成功")

        p = multiprocessing.Process(target=task,args=(client,))
        p.start()
    server.close()

def task(client):
    request_data = client.recv(1024).decode('utf-8')
    if len(request_data) == 0:
        client.close()
    else:
        request_path = request_data.split(' ')[1]
        print("请求地址是: ",request_path)

        print("request:  ",request_path)

        if request_path == '/':
            request_path = 'index1.html'

        try:
            with open('./'+request_path,'rb') as f:
                file_con = f.read()
        except Exception as e:
            response_line = "HTTP/1.1 404 NOT FOUND\r\n"
            response_head = "Server: PSWS1.1\r\n"
            with open('./err.html','rb') as f:
                error_data = f.read()

            response_data = (response_line+response_head+'\r\n').encode('utf-8') + error_data

            client.send(response_data)

        else:
            response_line = "HTTP/1.1 200 OK\r\n"
            response_head = "Server: PSWS1.1\r\n"
            with open('./'+request_path,'rb') as f:
                response_body = f.read()

            response_data = (response_line+response_head+'\r\n').encode() + response_body

            client.send(response_data)
        finally:
            client.close()


if __name__ == '__main__':
    serv_start(7777)




 

6.面向对象多任务

import multiprocessing
import socket


class server_start(object):
    def __init__(self,port):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.server.bind(("", port))
        self.server.listen(128)



    def start(self):
        while True:
            client,ip_port = self.server.accept()
            print(f"客户端{ip_port[0]} 使用{ip_port[1]} 端口连接成功")

            p = multiprocessing.Process(target=self.task,args=(client,))
            p.start()
        self.server.close()

    def task(self,client):
        request_data = client.recv(1024).decode('utf-8')
        if len(request_data) == 0:
            client.close()
        else:
            request_path = request_data.split(' ')[1]
            print("请求地址是: ",request_path)

            print("request:  ",request_path)

            if request_path == '/':
                request_path = 'index1.html'

            try:
                with open('./'+request_path,'rb') as f:
                    file_con = f.read()
            except Exception as e:
                response_line = "HTTP/1.1 404 NOT FOUND\r\n"
                response_head = "Server: PSWS1.1\r\n"
                with open('./err.html','rb') as f:
                    error_data = f.read()

                response_data = (response_line+response_head+'\r\n').encode('utf-8') + error_data

                client.send(response_data)

            else:
                response_line = "HTTP/1.1 200 OK\r\n"
                response_head = "Server: PSWS1.1\r\n"
                with open('./'+request_path,'rb') as f:
                    response_body = f.read()

                response_data = (response_line+response_head+'\r\n').encode() + response_body

                client.send(response_data)
            finally:
                client.close()


if __name__ == '__main__':
    server_start(7777).start()


结语

点赞👍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

anaconda ubuntu安装

1、下载anaconda 地址:https://www.anaconda.com/download#downloads 我是x86 64位系统,所以选择第一个 2、安装 执行命令: sh Anaconda3-2023.03-1-Linux-x86_64.sh中间会有几个过程 enter 确定 yes 确定 最后默认安装位置为&#xff1…

const、let、var区别

const、let、var区别 0、前言1、区别2、示例2.1 提前调用报错2.2 const与 let 定义的变量不能重复2.3 const与 let定义的变量如果在{}中只能在{}中调用2.4 const定义的变量不能重复赋值。 0、前言 let和const是ES6新增的声明变量的关键词,之前声明变量的关键词是var…

SpringBoot+mybatis教务管理系统

项目介绍 主要功能: 这个项目是一个教务管理系统,其中有三种角色:管理员,教师,学生 管理员权限: 管理员:对课程、学生信息、教师信息等进行增删改查,修改个人密码,修改学…

服务日志性能调优,由log引出的巨坑

只有被线上服务问题毒打过的人才明白日志有多重要! 谁赞成,谁反对?如果你深有同感,那恭喜你是个社会人了:) 日志对程序的重要性不言而喻,轻巧、简单、无需费脑,程序代码中随处可见…

新项目之初性能测试工作如何前移?

最近刚接手一个新项目,在最开始的时候要求对这个项目做性能测试,产品经理也给不出性能需求,只因为这个项目是电商项目,可能会有高并发,秒杀的场景,所以产品经理要求我们对这个项目必须做性能测试&#xff0…

Linux内核中内存管理相关配置项的详细解析16

接前一篇文章:Linux内核中内存管理相关配置项的详细解析15 三十五、Data Access Monitoring 此项展开后如下图所示: “DAMON: Data Access Monitoring Framework”项默认不选中。如果将其选中,则页面变为: 1. DAMON: Data Access…

关于 vue2 后台管理系统构建 vue2+mock.js 的经典案例

一,初识 Mock.js 1.什么是 mock.js: 主要是模拟数据生成器,可以生成随机数据,拦截器 Ajax 请求 2.为什么要使用 mock.js 由于很多学生在学习过程中,后端还没有做好接口,写好接口文档,有了mock.js 前端就…

2023VALSE目标跟踪相关的Poster

前沿:本博文分享了2023 中国无锡举办的VALSE 中与目标跟踪相关的Poster。 1. Weakly Alignment-Free RGBT Salient Object Detection With Deep Correlation Network IEEE TRANSACTIONS ON IMAGE PROCESSING, VOL. 31, 20 摘要:RGBT显著性目标检测&am…

Linux5.4 Mysql数据库初体验及管理

文章目录 计算机系统5G云计算第四章 LINUX Mysql数据库初体验及管理一、数据库相关概念1. 数据 (Data)的概念2.表的概念3.数据库的概念4.数据库管理系统5.数据库系统 二、数据库的发展1.第一代数据库2.第二代数据库3.第三代数据库 三、主流的数据库介绍四、关系数据库1.概念2.E…

最强Postman替代品,国产软件Apifox到底有对牛?

目录 前言: 接口管理现状 一、常用解决方案 二、存在的问题 Apifox 解决方案 一、如何解决这些问题 二、Apifox 做的不仅仅是数据打通 三、后续功能规划 四、更多 Apifox 功能截图 前言: Apifox是一款国产的API接口管理工具,可以帮…

Linux之用户组管理

目录 Linux之用户组管理 创建用户组 --- groupadd命令 语法格式 参数及作用 案例 添加/删除组成员 --- gpasswd命令 命令格式 参数及作用 案例 修改用户组属性 --- groupmod命令 语法格式 参数及作用 案例 删除组账户 --- groupdel命令 语法格式 案例 用户和组…

ASP.NET实验室信息管理系统源码 LIMS系统源码

ASP.NET实验室信息管理系统源码 LIMS系统源码 lims 实验室信息管理系统(LIMS)。它是由计算机硬件和应用软件组成,能够完成实验室数据和信息的收集、分析、报告和管理。 LIMS实验室信息管理系统专门针对实验室的整体环境而设计,以…

两个链表相加

描述 假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。 给定两个这种链表,请生成代表两个整数相加值的结果链表。 数据范围:0≤n,m≤1000000,链表任意值 0≤val≤9 要求:空间复杂度 O(n)…

Docker使用记录

文章目录 Docker基本使用Docker配置查看状态卸载安装使用 apt 存储库安装在 Ubuntu 上安装 Docker 桌面(非必要) Docker实例使用现有的镜像查找镜像拖取镜像列出镜像列表更新镜像导出镜像删除镜像导入镜像清理镜像查看容器导出容器导入容器-以镜像的方式创建容器重启容器进入容…

Springboot Apollo配置yml

1.背景: 项目都是配置的Apollo配置中心来进行配置的。新功能需要yml格式的数据(层级结构更清晰) 2.问题: 1)Apollo是否支持yml格式的配置信息? 2)配置好了以后读取不到Apollo配置的yml。 3…

平心而论,做电商数据分析还得这款大数据分析平台

各个业务系统上的数据能放一起分析了吗?根据物流周期做好库存计划了吗?广告投入分析评估报表出来吗?运营、物流、财务等部门环节间的信息脱节解决了吗?做电商数据分析不仅仅是做一两个销售分析报表,而是要综合各个部门…

vue3 - 内置组件Teleport的使用

<Teleport> 是一个内置组件&#xff0c;它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。 1&#xff0c;使用场景&#xff1a; 一个组件模板的一部分在逻辑上从属于该组件&#xff0c;但从整个应用视图的角度来看&#xff0c;它在 DOM 中应该…

Python网络爬虫使用教程

文章目录 一、URL资源抓取1.urllib2.requests3.requests-html二、正则表达式三、数据解析1.Beautiful Soup2.lxml3.selectolax四、自动化爬虫selenium五、爬虫框架1.Scrapy2.pyspider框架六、模拟登录与验证码识别七、autoscraper&#xff08;不需要编程基础&#xff09; 一、U…

小鱼深度产品测评之:阿里云新款通用算力型ECS云服务器Universal实例,实力与能力并存的一款产品。

ECS U实例评测 1、引言2、购买流程3、向导展示4、实例4.1 创建实例4.2 迁移上云4.3 查询功能4.3.1 下拉框选项4.3.2 查询结果保存 4.4 默认定位4.5 分组4.6 监控4.6.1 查看监控大盘4.6.2 自定义报警规则4.6.3 一键报警 4.7 列表操作4.7.1 资源变配4.7.2 远程链接4.7.3 续费 4.8…

深入探究测试用例设计的底层逻辑

测试用例是每位测试人员都绕不开的话题&#xff0c;也是大家习以为常的事情。几乎所有测试相关的公众号、博客、专栏&#xff0c;都会提及测试用例&#xff0c;由此可见它的重要性。但是&#xff0c;有许多从业者&#xff0c;对测试用例的设计仍然依靠经验积累&#xff0c;即使…