找回密码
 会员注册
查看: 31|回复: 0

pythonPython中的Socket编程底层原理解析与应用实战

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-5 11:52:08 | 显示全部楼层 |阅读模式
✨✨欢迎大家来到景天科技苑✨✨🎈🎈养成好习惯,先赞后看哦~🎈🎈🏆作者简介:景天科技苑🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。🏆《博客》:Python全栈,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。所属的专栏:python综合应用,基础语法到高阶实战教学景天的主页:景天科技苑文章目录Python中的Socket编程一、基本概念二、Python中的Socket编程2.1常见的套接字对象方法和属性2.2创建TCP服务和客户端2.2.1创建TCP服务2.2.2创建TCP客户端2.3创建UDP服务和客户端2.3.1创建UDP服务器2.3.2创建UDP客户端三、实际案例:简单的聊天室应用四、高级话题和最佳实践1.异步Socket编程2.错误处理和异常3.安全性4.性能和优化5.调试和日志记录五、总结Python中的Socket编程Socket编程是网络通信的基础,Python通过内置的socket模块提供了强大的网络编程接口。Socket编程允许开发者创建客户端和服务器程序,实现数据在网络中的传输。本文将结合实际案例,详细介绍Python中Socket编程的基本概念、常用方法和实际应用。一、基本概念服务器与客户端服务器:一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需的“服务”。它响应客户端的请求,并等待更多的请求。客户端:向服务器请求服务的用户或程序。它发送请求并接收服务器的响应。套接字(Socket)套接字是计算机网络数据结构,它体现了通信端点的概念。在任何类型的通信开始之前,网络应用程序必须创建套接字。套接字可以被比作电话插孔,没有它将无法进行通信。Python中的socket模块支持多种类型的套接字,包括基于IPv4的AF_INET(流式套接字和数据报套接字)。流式套接字(SOCK_STREAM)用于提供面向连接、可靠的数据传输服务。它基于TCP协议,确保数据按顺序、无差错、不重复地传输。数据报套接字(SOCK_DGRAM)提供一种无连接的服务。数据报套接字基于UDP协议,不保证数据传输的可靠性,数据可能在传输过程中丢失或重复,且无法保证顺序地接收到数据。二、Python中的Socket编程2.1常见的套接字对象方法和属性在Python的socket编程中,常用的方法包括:socket():创建一个新的套接字对象。bind():将套接字绑定到特定的IP地址和端口号上。listen():开始监听客户端的连接请求。accept():接受一个连接请求,并返回一个新的套接字对象和客户端的地址信息。connect():客户端使用该方法连接到服务器。send()/sendall():发送数据到连接的套接字。sendall()确保数据被完整发送。recv()/recvfrom():接收数据。recv()用于TCP连接,recvfrom()用于UDP连接。close():关闭套接字。2.2创建TCP服务和客户端2.2.1创建TCP服务创建一个简单的TCP服务器,步骤如下:导入socket模块。创建套接字对象,指定AF_INET和SOCK_STREAM。绑定套接字到IP地址和端口号。调用listen()方法监听连接请求。使用accept()方法接受连接请求,进入通信循环。在通信循环中,使用recv()接收数据,使用send()或sendall()发送数据。关闭套接字。importsocketHOST='127.0.0.1'#监听所有可用接口PORT=9001ADDR=(HOST,PORT)BUFSIZ=1024deftcp_server():withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:s.bind(ADDR)s.listen()print('等待用户接入...')whileTrue:conn,addr=s.accept()withconn:print(f'连接来自{addr}')whileTrue:data=conn.recv(BUFSIZ)ifnotdata:breakprint(f'收到数据:{data.decode()}')conn.send(data)#Echo服务器,原样返回数据if__name__=='__main__':tcp_server()123456789101112131415161718192021222324252.2.2创建TCP客户端创建TCP客户端的步骤如下:导入socket模块。创建套接字对象,指定AF_INET和SOCK_STREAM。使用connect()方法连接到服务器。进入通信循环,使用send()发送数据,使用recv()接收数据。关闭套接字。importsocketHOST='127.0.0.1'PORT=9001ADDR=(HOST,PORT)BUFSIZ=1024deftcp_client():withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:s.connect(ADDR)print('连接服务成功!!')whileTrue:data=input('请输入数据:')ifdata=='q':breaks.send(data.encode())recved=s.recv(BUFSIZ).decode()print(f'收到服务器响应:{recved}')if__name__=='__main__':tcp_client()123456789101112131415161718192021客户端输入消息,收到服务端同样的返回2.3创建UDP服务和客户端UDP服务与TCP服务的主要区别在于无连接和不可靠的数据传输。2.3.1创建UDP服务器UDP服务器通常不需要监听连接请求,因为它不建立持久的连接。服务器只需绑定到特定端口,并等待接收数据。importsocketHOST='127.0.0.1'PORT=9002BUFSIZ=1024ADDR=(HOST,PORT)defudp_server():withsocket.socket(socket.AF_INET,socket.SOCK_DGRAM)ass:s.bind(ADDR)print('UDP服务器启动...')whileTrue:data,addr=s.recvfrom(BUFSIZ)print(f'收到来自{addr}的数据:{data.decode()}')resp='收到您的消息!'.encode()s.sendto(resp,addr)if__name__=='__main__':udp_server()123456789101112131415161718192.3.2创建UDP客户端UDP客户端向服务器发送数据,并等待接收响应(尽管这不是必须的,因为UDP是无连接的)。importsocketHOST='127.0.0.1'PORT=9002BUFSIZ=1024ADDR=(HOST,PORT)defudp_client():withsocket.socket(socket.AF_INET,socket.SOCK_DGRAM)ass:whileTrue:data=input('请输入数据(输入q退出):')ifdata=='q':breaks.sendto(data.encode(),ADDR)resp,server=s.recvfrom(BUFSIZ)print(f'收到服务器响应:{resp.decode()}')if__name__=='__main__':udp_client()12345678910111213141516171819客户端输入消息,也能收到服务端消息三、实际案例:简单的聊天室应用以下是一个简单的TCP聊天室应用,它包含一个服务器和多个客户端。服务器将来自任一客户端的消息广播给所有已连接的客户端。TCP聊天室服务器importsocketimportthreadingHOST='localhost'PORT=9003BUFSIZ=1024ADDR=(HOST,PORT)clients=[]defhandle_client(conn,addr):print(f'连接来自{addr}')conn.send('欢迎来到聊天室!'.encode())clients.append(conn)try:whileTrue:data=conn.recv(BUFSIZ)ifnotdata:breakbroadcast(data,conn)finally:conn.close()clients.remove(conn)defbroadcast(data,sender):forclientinclients:print("打印客户端",client)print("打印客户端发来的数据",data.decode())ifclient==sender:try:#将客户端的原文发动给客户端sender.send(data)except:clients.remove(client)defmain():withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:s.bind(ADDR)s.listen()print('等待用户接入...')whileTrue:conn,addr=s.accept()thread=threading.Thread(target=handle_client,args=(conn,addr))thread.start()if__name__=='__main__':main()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647TCP聊天室客户端importsocketHOST='localhost'PORT=9003BUFSIZ=1024ADDR=(HOST,PORT)defchat_client():withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:s.connect(ADDR)print(s.recv(BUFSIZ).decode())whileTrue:data=input('请输入消息(输入q退出):')ifdata=='q':breaks.send(data.encode())ifdata.lower()=='bye':breakprint(s.recv(BUFSIZ).decode())if__name__=='__main__':chat_client()12345678910111213141516171819202122我们也可以运行好几个客户端,服务端打印哪个客户端连过来当然,我们可以继续深入讨论Socket编程及其在Python中的应用,包括一些高级话题和最佳实践。以下是一些扩展内容:四、高级话题和最佳实践1.异步Socket编程Python的asyncio库提供了对异步IO的支持,这使得编写非阻塞的Socket客户端和服务器变得更加容易。使用asyncio,你可以编写出性能更高、响应更快的网络应用程序。异步TCP服务器示例importasyncioasyncdefhandle_echo(reader,writer):data=awaitreader.read(100)message=data.decode()addr=writer.get_extra_info('peername')print(f"Received{message}from{addr}")print(f"Send:{message.upper()}to{addr}")writer.write(message.upper().encode())awaitwriter.drain()print("Closetheconnection")writer.close()asyncdefmain():server=awaitasyncio.start_server(handle_echo,'127.0.0.1',8888)addr=server.sockets[0].getsockname()print(f'Servingon{addr}')asyncwithserver:awaitserver.serve_forever()asyncio.run(main())1234567891011121314151617181920212223242526异步TCP客户端示例importasyncioasyncdeftcp_echo_client(message,host,port):reader,writer=awaitasyncio.open_connection(host,port)print(f'Send:{message}')writer.write(message.encode())data=awaitreader.read(100)print(f'Received:{data.decode()}')writer.close()asyncio.run(tcp_echo_client('Hello,world!','127.0.0.1',8888))12345678910111213142.错误处理和异常在网络编程中,处理各种网络错误和异常是非常重要的。例如,连接超时、连接中断、数据发送失败等都是常见的错误情况。在Python中,你可以通过try...except块来捕获和处理这些异常。例如,使用socket.timeout来处理连接超时,使用socket.error来处理一般的socket错误。3.安全性当编写网络应用程序时,安全性是一个重要的考虑因素。以下是一些提升Socket程序安全性的方法:使用SSL/TLS来加密数据传输。Python的ssl模块可以与socket模块一起使用来创建安全的socket连接。验证客户端的身份(如果需要的话)。可以使用证书、密钥或令牌等方式来验证客户端的合法性。限制可以连接到服务器的IP地址或端口范围。这可以通过防火墙规则或服务器软件中的设置来实现。4.性能和优化Socket编程的性能优化可以涉及多个方面,包括网络延迟、吞吐量、并发处理能力等。以下是一些优化技巧:使用非阻塞或异步IO来减少等待时间。使用合适的缓冲区大小来平衡内存使用和网络性能。使用多线程或多进程来处理多个并发连接。压缩数据以减少传输量,特别是当数据量大时。使用缓存来存储常用数据,减少对后端服务的请求。5.调试和日志记录在网络编程中,调试和日志记录是非常重要的工具。它们可以帮助你理解程序的行为,诊断问题,并优化性能。使用Python的logging模块来记录程序的运行状态、错误信息和警告。在关键位置添加调试语句或断点,以便在出现问题时能够追踪程序的执行流程。使用网络抓包工具(如Wireshark)来捕获和分析网络数据包,了解数据的实际传输情况。五、总结Socket编程是构建网络应用程序的基础。通过掌握Socket编程的基本概念、TCP和UDP的使用方法,以及异步编程、错误处理、安全性、性能和调试等高级话题,你可以开发出高效、稳定、安全的网络应用程序。希望本文对你有所帮助!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 06:28 , Processed in 0.423097 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表