python高级-socket和web相关

news/2024/5/14 3:36:31/文章来源:https://blog.csdn.net/bmxch/article/details/131188158

目录

一、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 socketif __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)#接收数据,这次接受的数据最大字节数是1024recv_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 socketif __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 threadingdef 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)breakservice_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)#多客户端socketwhile 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 threadingclass 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):#多客户端socketwhile 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]} 已断开连接,下次再见。。。。')breaksend_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 socketif __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 socketdef 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_dataclient.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_bodyclient.send(response_data)finally:client.close()if __name__ == '__main__':serv_start(7777)

 

6.面向对象多任务

import multiprocessing
import socketclass 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_dataclient.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_bodyclient.send(response_data)finally:client.close()if __name__ == '__main__':server_start(7777).start()


结语

点赞👍

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

001、体系结构之概述

1.TiDB简介 TiDB 是 PingCAP 公司⾃主设计、研发的开源分布式关系型数据库,是⼀款同时⽀持在线事务处理与在线分析处理 (Hybrid Transactional and Analytical Processing,HTAP) 的融合型分布式数据库产品,具备⽔平扩容或者缩容、⾦融级⾼可⽤、实时HTA…

两个链表相加

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

智慧矿山成行业新趋势,千寻位置助力企业数字化转型

随着政策推动和科技发展,智慧矿山已成为矿业行业的趋势和未来的方向。 智慧矿山就是以矿山数字化、信息化为前提和基础,对矿山生产、人员健康与安全、技术支持与后勤保障等进行主动感知、自动分析、快速处理,最终实现安全矿山、无人矿山、高效…

3ds Max - Pivot Painter Tool

很久之前的笔记,整理归档; Pivot Painter Tool是3dsMax中的插件,主要是辅助将Mesh中每个Element生成自己的Pivot Position,方便如使用World Position Offset对每个Element进行精确控制,导入使用Pivot Painter Tool工具…

java读取文件内容

直接上代码,两个类:一个工具类,一个测试类 工具类代码: package org.example.study.util;import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils;import java.io.*; import java.nio.charset.Charset…

企业转型在搭建BI时,需要注意什么

如今,商业智能BI在全世界范围内掀起了一股热潮,形成了一个庞大的市场,在信息化时代,企业需要借助BI来进行更好的成长。 在这种全新的社会、商业BI环境下,各行各业的企业都开始寻求探索新的商业模式,通过转…

python + pytest 接口自动化 —— 参数关联

什么是参数关联? 参数关联,也叫接口关联,即接口之间存在参数的联系或依赖。在完成某一功能业务时,有时需要按顺序请求多个接口,此时在某些接口之间可能会存在关联关系。 比如:B接口的某个或某些请求参数是…

Spring Security--会话管理

就像登录qq一样,一个手机登录会将另外一个手机挤下线,这个就叫会话管理。 这个东西非常简单,在默认情况下可以登录n多次,一旦开启,就不允许登录多个。 什么是一个会话。 我们简单理解就是一个浏览器的同一个用户算一…

0基础转行,网路工程和网络安全哪个更有发展前景?

对于初学者而言,初入IT行业最重要的就是选择一个热门且前景好的职业,而网络工程和网络安全作为IT行业的热门职业必然成为很多人的首选,那么网络工程和网络安全哪个发展前景好?小编带大家详细了解一下。 首先,我们对网络工程和网络…

聊一聊近期测试行情以及个人的感受

众所周知,去年年底的裁员潮再加上今年的疫情影响,失业、找工作成为了蛮多人的当务之急。最近一些招聘网站也出现被刷爆的情况,其中顺利找到工作的并不多,说明行情很冷,但是总有许多人顺利跳槽。 其实对于大牛来说&…

工具篇--4 消息中间件-RabbitMq 模型介绍

1 介绍: RabbitMQ 是一个开源的消息中间件,它实现了 AMQP(高级消息队列协议)标准,并且支持多种语言和操作系统,包括 Java、Python、Ruby、PHP、.NET、MacOS、Windows、Linux 等等。RabbitMQ 提供了可靠的消息传递机制…

号称 Java 面试八股文天花板(2023 最新版)首次开源

咱们先来说说: 最近感慨面试难的人越来越多了,一方面是市场环境,更重要的一方面是企业对 Java 的人才要求越来越高了。 基本上这样感慨的分为两类人,第一,虽然挂着 3、5 年经验,但肚子里货少,也…

Element常用组件之 表单组件 form

1. 建立form.vue <template><el-form ref"form" :model"form" label-width"80px"><el-form-item label"活动名称"><el-input v-model"form.name"></el-input></el-form-item><el-f…

怎样高效率备考PMP

一方面由于这些考试的知识&#xff0c;在准备考试前我们大部分很少接触&#xff0c;大部分人考试的目的也未必是感兴趣&#xff0c;更多是因为考试结果能给我们带来的收益。因此长时间的学习不熟悉甚至不感兴趣的很容易疲倦&#xff0c;这不像我们工作或生活中的一些技能&#…

Springboot Apollo配置yml

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

从美颜算法到AI美颜SDK:美丽的背后隐藏着什么?

在年轻人的生活中&#xff0c;通过美颜SDK类型的美颜工具进行拍摄已经成为了一种全新的文化现象。时下&#xff0c;AI美颜、美颜SDK讨论热点极高&#xff0c;那么大家知道美颜算法和AI美颜到底有什么不同吗&#xff1f;它们背后隐藏着什么样的技术和思想&#xff1f; 一、美颜算…

Visual Studio Code Arduino资源占用和效率对比

Visual Studio Code&Arduino资源占用和效率对比 系统资源占用&#xff1a;编译效率&#xff1a; 这段时间在玩ESP32&#xff0c;闲来无事对比了一下Visual Studio Code后面简称VS和Arduino的效率和资源占用&#xff0c;只是大致的对比&#xff0c;没有斤斤计较。 配置为&am…

防雷抗浪涌插排插座推荐,同为科技(TOWE)防雷桌面PDU安全可靠

同为科技TOWE双排防雷抗浪涌桌面PDU插座 随着夏天天气越来越热&#xff0c;强对流天气增多&#xff0c;雷雨天气频发。在雷电季节&#xff0c;通常影响家用电器安全的主要原因是由于雷电感应的侵入&#xff0c;特别是对绝缘强度低、过电压耐受力差的微电子产品影响甚大。而所谓…

【spring源码系列-05】refresh中prepareRefresh方法的执行流程

Spring源码系列整体栏目 内容链接地址【一】spring源码整体概述https://blog.csdn.net/zhenghuishengq/article/details/130940885【二】通过refresh方法剖析IOC的整体流程https://blog.csdn.net/zhenghuishengq/article/details/131003428【三】xml配置文件启动spring时refres…

Golang | Web开发之Gin多服务配置及优雅关闭平滑重启

欢迎关注「全栈工程师修炼指南」公众号 点击 &#x1f447; 下方卡片 即可关注我哟! 设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习&#xff01; 专注 企业运维实践、网络安全、系统运维、应用开发、物联网实战、全栈文章 等知识分享 “ 花开堪折直须折&#xf…