如何用Python进行网络编程(Socket)?

Python Socket编程中TCP与UDP的核心差异在于:TCP是面向连接、可靠的协议,适用于文件传输等需数据完整性的场景;UDP无连接、速度快,适合实时音视频、游戏等对延迟敏感的应用。选择依据是对可靠性与速度的需求权衡。

如何用python进行网络编程(socket)?

使用Python进行网络编程,核心在于其内置的

socket

模块。它提供了一套标准接口,让程序能够像打电话一样,通过IP地址和端口号与其他程序建立连接,进行数据交换。无论是构建一个简单的聊天客户端,还是复杂的服务器应用,我们都是围绕着创建socket、绑定/连接、监听/发送/接收这些基本操作来展开的。这不仅仅是技术细节,更是一种通信思维的体现,让不同的程序能够在网络空间中“对话”。

解决方案

Python的

socket

模块是进行网络编程的基石。这里我将通过一个简单的TCP客户端和服务器的例子,来展示其基本用法。

服务器端代码示例:

import socketimport threading # 后面会提到多线程,这里先引入HOST = '127.0.0.1'  # 服务器监听的IP地址PORT = 65432        # 服务器监听的端口def handle_client(conn, addr):    """处理单个客户端连接的函数"""    print(f"Connected by {addr}")    try:        while True:            data = conn.recv(1024) # 接收客户端数据,最大1024字节            if not data: # 如果没有数据,说明客户端断开连接                print(f"Client {addr} disconnected.")                break            message = data.decode('utf-8')            print(f"Received from {addr}: {message}")            # 回复客户端            response = f"Server received: {message}"            conn.sendall(response.encode('utf-8'))    except ConnectionResetError:        print(f"Client {addr} forcibly closed the connection.")    except Exception as e:        print(f"Error handling client {addr}: {e}")    finally:        conn.close() # 关闭客户端连接with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:    s.bind((HOST, PORT)) # 绑定IP地址和端口    s.listen() # 开始监听,等待客户端连接    print(f"Server listening on {HOST}:{PORT}")    while True:        conn, addr = s.accept() # 接受新的客户端连接        # 为每个新连接创建一个线程来处理,避免阻塞主进程        client_thread = threading.Thread(target=handle_client, args=(conn, addr))        client_thread.start()

客户端代码示例:

立即学习“Python免费学习笔记(深入)”;

import socketHOST = '127.0.0.1'  # 服务器的IP地址PORT = 65432        # 服务器的端口with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:    try:        s.connect((HOST, PORT)) # 连接到服务器        print(f"Connected to {HOST}:{PORT}")        message_to_send = "Hello, server! This is client."        s.sendall(message_to_send.encode('utf-8')) # 发送数据        data = s.recv(1024) # 接收服务器的回复        print(f"Received from server: {data.decode('utf-8')}")    except ConnectionRefusedError:        print("Connection refused. Is the server running?")    except Exception as e:        print(f"An error occurred: {e}")    finally:        print("Client closing connection.")        # s.close() # with 语句块结束时会自动关闭

在这些例子中,

socket.AF_INET

指定了使用IPv4地址族,

socket.SOCK_STREAM

则表示使用TCP协议(流式套接字)。服务器通过

bind()

绑定地址,

listen()

开始监听,然后

accept()

接受连接。每个

accept()

返回一个新的套接字对象

conn

,用于与特定客户端通信,以及客户端的地址

addr

。客户端则直接使用

connect()

连接服务器。数据传输时,需要注意字符串和字节串之间的编码(

encode()

)和解码(

decode()

)。

Python Socket编程中TCP与UDP的选择与核心差异是什么?

在Python的Socket编程中,我们通常会选择TCP(传输控制协议)或UDP(用户数据报协议)。这两种协议各有优劣,选择哪一个往往取决于你的应用场景对数据可靠性和传输速度的需求。

TCP (Transmission Control Protocol)TCP是一种面向连接的协议。这意味着在数据传输之前,客户端和服务器之间必须先建立一个可靠的连接。它提供:

可靠性: TCP确保数据能够无差错、按顺序地到达目的地。如果数据包丢失或损坏,TCP会自动重传。有序性: 数据会按照发送的顺序接收。流量控制: 防止发送方发送数据过快,导致接收方无法处理。拥塞控制: 避免网络过载。

何时选择TCP?我个人在开发需要高度数据完整性的应用时,比如文件传输、网页浏览(HTTP)、电子邮件(SMTP/POP3/IMAP)或数据库连接时,总是优先考虑TCP。它的可靠性省去了很多手动处理数据丢失和乱序的麻烦,虽然会带来一些额外的开销和延迟,但这种“省心”的特性对于大多数业务应用来说是值得的。

在Python中,创建TCP Socket使用

socket.socket(socket.AF_INET, socket.SOCK_STREAM)

UDP (User Datagram Protocol)UDP是一种无连接的协议。它不保证数据的可靠传输,也不保证数据包的顺序。每个UDP数据报都是一个独立的单元,发送后就“不管不顾”了。

不可靠性: 数据包可能丢失、重复或乱序。无序性: 接收到的数据包顺序可能与发送顺序不同。速度快: 由于没有建立连接的握手过程,也没有重传、流量控制等机制,UDP的传输速度通常比TCP快。开销小: 头部信息比TCP小,对系统资源占用少。

何时选择UDP?对于那些对实时性要求极高,但可以容忍少量数据丢失的应用,UDP是更好的选择。比如在线游戏、实时音视频流(VoIP)、DNS查询等。在这种场景下,如果一个数据包丢失了,重传它反而会增加延迟,不如直接发送下一个数据包,让应用层去处理可能的“瑕疵”。在我看来,如果你需要自己实现复杂的可靠性机制,或者对延迟有极致要求,才会考虑UDP。

在Python中,创建UDP Socket使用

socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

。UDP的发送和接收方法也不同,它使用

sendto()

recvfrom()

,因为每次发送都需要指定目标地址,接收时也会返回发送方的地址。

总结来说,TCP是“严谨的信使”,确保每一封信都准确无误、按时送达;UDP则是“快速的广播员”,信息发出去就不管了,谁收到算谁的,但速度绝对快。根据你对“信息”的重视程度,做出合适的选择。

如何处理Python Socket编程中的常见错误和异常?

在Python Socket编程中,网络环境的复杂性和不可预测性意味着错误和异常是常态。不恰当的错误处理轻则导致程序崩溃,重则引发数据丢失或安全问题。我的经验是,预见并妥善处理这些异常,是构建健壮网络应用的关键。

以下是一些常见的Socket错误和它们的处理策略:

ConnectionRefusedError

(连接被拒绝):

场景: 客户端尝试连接一个不存在的服务器、服务器未启动、或者服务器防火墙阻止了连接。处理: 在客户端的

connect()

调用周围使用

try...except ConnectionRefusedError:

捕获。可以尝试重试连接,或者向用户显示错误信息。

ConnectionResetError

(连接被重置):

场景: 通常发生在服务器端,当客户端在没有正常关闭连接的情况下突然断开(例如,客户端程序崩溃、网络中断)。服务器尝试向已关闭的连接写入或读取时会触发。处理: 在服务器的

recv()

send()

循环中捕获此异常。一旦捕获,意味着客户端已断开,应该关闭对应的客户端socket并清理资源。

BrokenPipeError

(管道破裂):

企业网站通用源码1.0 企业网站通用源码1.0

企业网站通用源码是以aspcms作为核心进行开发的asp企业网站源码。企业网站通用源码是一套界面设计非常漂亮的企业网站源码,是2016年下半年的又一力作,适合大部分的企业在制作网站是参考或使用,源码亲测完整可用,没有任何功能限制,程序内核使用的是aspcms,如果有不懂的地方或者有不会用的地方可以搜索aspcms的相关技术问题来解决。网站UI虽然不是特别细腻,但是网站整体格调非常立体,尤其是通观全

企业网站通用源码1.0 0 查看详情 企业网站通用源码1.0 场景: 当你试图向一个已经关闭的socket写入数据时,会抛出此错误。它与

ConnectionResetError

有些相似,但通常发生在尝试

send()

时。处理: 类似

ConnectionResetError

,在发送数据前检查连接状态,或者在

send()

调用周围捕获。一旦发生,说明连接已不可用。

TimeoutError

(超时错误):

场景: 当socket操作(如

connect()

,

recv()

,

send()

,

accept()

) 在指定时间内没有完成时发生。处理: 可以通过

socket.settimeout(seconds)

方法为socket设置一个超时时间。在

try...except TimeoutError:

中捕获,然后决定是重试、跳过还是报告错误。这对于防止程序长时间阻塞在网络操作上非常重要。

BlockingIOError

(阻塞IO错误):

场景: 当socket设置为非阻塞模式(

socket.setblocking(False)

)后,如果一个操作(如

recv()

)会阻塞,就会立即抛出此错误。处理: 这不是一个真正的错误,而是非阻塞模式下的一种预期行为。通常与

select

selectors

asyncio

等异步I/O机制结合使用,表示当前没有数据可读或不可写,需要稍后再试。

OSError

(操作系统错误):

场景: 这是一个更通用的错误,

socket.error

在Python 3.3+中被

OSError

取代。它可能包含上述所有特定错误,也可能包含其他系统级别的网络错误,例如“地址已被使用”(

Address already in use

)当服务器尝试绑定一个已被占用的端口时。处理: 对于“地址已被使用”错误,可以尝试更改端口,或者在服务器关闭后等待一段时间再启动。对于其他通用的

OSError

,通常需要查看其错误码或错误信息以进行具体判断。

通用处理策略:

使用

try...except

块: 这是Python处理异常的基本方式。将所有可能抛出异常的网络操作放入

try

块中,并在

except

块中处理。

finally

块: 确保在

finally

块中关闭socket连接和释放资源,无论是否发生异常。

with socket.socket(...) as s:

语句在Python 3中是更好的实践,它能自动管理socket的关闭。日志记录: 记录捕获到的异常信息,包括时间、错误类型、错误消息和相关上下文,这对于调试和问题排查至关重要。优雅关闭: 在关闭socket之前,尝试使用

socket.shutdown(socket.SHUT_RDWR)

来通知对端不再发送或接收数据,这有助于更优雅地断开连接。

记住,网络是不可靠的。与其期望一切顺利,不如假设一切都会出错,并为每一种可能的情况做好准备。这虽然增加了代码的复杂度,但大大提升了程序的健壮性和用户体验。

Python Socket服务器如何实现多客户端并发连接?

一个基本的Python Socket服务器,如果不做特殊处理,一次只能处理一个客户端连接。当它在

conn.recv()

conn.send()

上阻塞时,其他等待连接的客户端就只能排队。这显然无法满足现代网络应用的需求。实现多客户端并发连接,是构建实用网络服务的必经之路。

有几种主流的方法可以解决这个问题,每种方法都有其适用场景和权衡:

多线程(Threading)

原理: 每当服务器接受到一个新的客户端连接(

s.accept()

),就创建一个新的线程来处理这个客户端的通信。主线程继续监听新的连接。优点: 实现相对简单直观,每个客户端的处理逻辑可以独立编写。对于I/O密集型任务(即大部分时间在等待网络数据),Python的GIL(全局解释器锁)影响不大,因为线程在等待I/O时会释放GIL。缺点: 线程的创建和管理有一定开销。对于CPU密集型任务,由于GIL的存在,多线程并不能真正实现并行计算,只是并发执行。线程之间的共享数据需要加锁保护,否则可能出现竞态条件。适用场景: 中小型服务器应用,I/O操作较多,对CPU计算要求不高的场景。

我的示例代码中已经包含了多线程的简单实现,即在

s.accept()

后,调用

threading.Thread(target=handle_client, args=(conn, addr)).start()

多进程(Multiprocessing)

原理: 类似多线程,但每个客户端连接会分配到一个独立的进程来处理。优点: 进程之间内存独立,避免了GIL的限制,可以真正实现并行计算。一个进程崩溃不会影响其他进程。缺点: 进程创建和销毁的开销比线程大得多,更消耗系统资源。进程间通信(IPC)比线程间通信复杂。适用场景: 需要利用多核CPU进行并行计算的服务器,或者对隔离性要求较高的服务。

实现上,将

threading.Thread

替换为

multiprocessing.Process

即可,但需要注意进程间数据共享的问题。

异步I/O(Asynchronous I/O)

原理: 使用单线程或少量线程,通过事件循环(event loop)来管理多个I/O操作。当一个I/O操作(如

recv()

)会阻塞时,它不会停下来等待,而是注册一个回调函数,然后去处理其他客户端的I/O事件。当之前的I/O操作完成后,事件循环会调用相应的回调函数。Python的

asyncio

模块是实现异步I/O的官方推荐方式,它基于协程(coroutine)。优点: 极高的并发性能和扩展性,资源消耗远低于多线程/多进程。特别适合I/O密集型任务。缺点: 编程范式与传统的同步编程有很大不同,需要使用

async

await

关键字,学习曲线较陡峭。调试相对复杂。适用场景: 大规模高并发的网络服务,如Web服务器、API网关等。这是我个人在构建高性能网络服务时首选的方案。

一个

asyncio

的Socket服务器大致结构如下:

import asyncioasync def handle_client_async(reader, writer):    addr = writer.get_extra_info('peername')    print(f"Connected by {addr}")    try:        while True:            data = await reader.read(1024) # 异步读取            if not data:                print(f"Client {addr} disconnected.")                break            message = data.decode('utf-8')            print(f"Received from {addr}: {message}")            response = f"Server received: {message}"            writer.write(response.encode('utf-8')) # 异步写入            await writer.drain() # 确保数据发送完成    except Exception as e:        print(f"Error handling client {addr}: {e}")    finally:        writer.close()        await writer.wait_closed() # 等待写入器关闭async def main_async():    server = await asyncio.start_server(        handle_client_async, '127.0.0.1', 65432    )    addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)    print(f"Serving on {addrs}")    async with server:        await server.serve_forever()# if __name__ == '__main__':#     asyncio.run(main_async())

选择哪种并发模型,没有绝对的答案,需要根据项目的具体需求、团队的技术栈以及预期的负载来决定。对于初学者,多线程是一个不错的起点,能够快速理解并发的机制。而对于追求极致性能和扩展性的场景,

asyncio

无疑是更现代、更强大的选择。

以上就是如何用Python进行网络编程(Socket)?的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/934022.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月29日 14:07:31
下一篇 2025年11月29日 14:07:50

相关推荐

  • 怎样用免费工具美化PPT_免费美化PPT的实用方法分享

    利用KIMI智能助手可免费将PPT美化为科技感风格,但需核对文字准确性;2. 天工AI擅长优化内容结构,提升逻辑性,适合高质量内容需求;3. SlidesAI支持语音输入与自动排版,操作便捷,利于紧急场景;4. Prezo提供多种模板,自动生成图文并茂幻灯片,适合学生与初创团队。 如果您有一份内容完…

    2025年12月6日 软件教程
    000
  • Pages怎么协作编辑同一文档 Pages多人实时协作的流程

    首先启用Pages共享功能,点击右上角共享按钮并选择“添加协作者”,设置为可编辑并生成链接;接着复制链接通过邮件或社交软件发送给成员,确保其使用Apple ID登录iCloud后即可加入编辑;也可直接在共享菜单中输入邮箱地址定向邀请,设定编辑权限后发送;最后在共享面板中管理协作者权限,查看实时在线状…

    2025年12月6日 软件教程
    100
  • REDMI K90系列正式发布,售价2599元起!

    10月23日,redmi k90系列正式亮相,推出redmi k90与redmi k90 pro max两款新机。其中,redmi k90搭载骁龙8至尊版处理器、7100mah大电池及100w有线快充等多项旗舰配置,起售价为2599元,官方称其为k系列迄今为止最完整的标准版本。 图源:REDMI红米…

    2025年12月6日 行业动态
    200
  • Linux中如何安装Nginx服务_Linux安装Nginx服务的完整指南

    首先更新系统软件包,然后通过对应包管理器安装Nginx,启动并启用服务,开放防火墙端口,最后验证欢迎页显示以确认安装成功。 在Linux系统中安装Nginx服务是搭建Web服务器的第一步。Nginx以高性能、低资源消耗和良好的并发处理能力著称,广泛用于静态内容服务、反向代理和负载均衡。以下是在主流L…

    2025年12月6日 运维
    000
  • Linux journalctl与systemctl status结合分析

    先看 systemctl status 确认服务状态,再用 journalctl 查看详细日志。例如 nginx 启动失败时,systemctl status 显示 Active: failed,journalctl -u nginx 发现端口 80 被占用,结合两者可快速定位问题根源。 在 Lin…

    2025年12月6日 运维
    100
  • 华为新机发布计划曝光:Pura 90系列或明年4月登场

    近日,有数码博主透露了华为2025年至2026年的新品规划,其中pura 90系列预计在2026年4月发布,有望成为华为新一代影像旗舰。根据路线图,华为将在2025年底至2026年陆续推出mate 80系列、折叠屏新机mate x7系列以及nova 15系列,而pura 90系列则将成为2026年上…

    2025年12月6日 行业动态
    100
  • TikTok视频无法下载怎么办 TikTok视频下载异常修复方法

    先检查链接格式、网络设置及工具版本。复制以https://www.tiktok.com/@或vm.tiktok.com开头的链接,删除?后参数,尝试短链接;确保网络畅通,可切换地区节点或关闭防火墙;更新工具至最新版,优先选用yt-dlp等持续维护的工具。 遇到TikTok视频下载不了的情况,别急着换…

    2025年12月6日 软件教程
    100
  • Linux如何优化系统性能_Linux系统性能优化的实用方法

    优化Linux性能需先监控资源使用,通过top、vmstat等命令分析负载,再调整内核参数如TCP优化与内存交换,结合关闭无用服务、选用合适文件系统与I/O调度器,持续按需调优以提升系统效率。 Linux系统性能优化的核心在于合理配置资源、监控系统状态并及时调整瓶颈环节。通过一系列实用手段,可以显著…

    2025年12月6日 运维
    000
  • Linux命令行中wc命令的实用技巧

    wc命令可统计文件的行数、单词数、字符数和字节数,常用-l统计行数,如wc -l /etc/passwd查看用户数量;结合grep可分析日志,如grep “error” logfile.txt | wc -l统计错误行数;-w统计单词数,-m统计字符数(含空格换行),-c统计…

    2025年12月6日 运维
    000
  • 曝小米17 Air正在筹备 超薄机身+2亿像素+eSIM技术?

    近日,手机行业再度掀起超薄机型热潮,三星与苹果已相继推出s25 edge与iphone air等轻薄旗舰,引发市场高度关注。在此趋势下,多家国产厂商被曝正积极布局相关技术,加速抢占这一细分赛道。据业内人士消息,小米的超薄旗舰机型小米17 air已进入筹备阶段。 小米17 Pro 爆料显示,小米正在评…

    2025年12月6日 行业动态
    000
  • 「世纪传奇刀片新篇」飞利浦影音双11声宴开启

    百年声学基因碰撞前沿科技,一场有关声音美学与设计美学的影音狂欢已悄然引爆2025“双十一”! 当绝大多数影音数码品牌还在价格战中挣扎时,飞利浦影音已然开启了一场跨越百年的“声”活革命。作为拥有深厚技术底蕴的音频巨头,飞利浦影音及配件此次“双十一”精准聚焦“传承经典”与“设计美学”两大核心,为热爱生活…

    2025年12月6日 行业动态
    000
  • 荣耀手表5Pro 10月23日正式开启首销国补优惠价1359.2元起售

    荣耀手表5pro自9月25日开启全渠道预售以来,市场热度持续攀升,上市初期便迎来抢购热潮,一度出现全线售罄、供不应求的局面。10月23日,荣耀手表5pro正式迎来首销,提供蓝牙版与esim版两种选择。其中,蓝牙版本的攀登者(橙色)、开拓者(黑色)和远航者(灰色)首销期间享受国补优惠价,到手价为135…

    2025年12月6日 行业动态
    000
  • Vue.js应用中配置环境变量:灵活管理后端通信地址

    在%ignore_a_1%应用中,灵活配置后端api地址等参数是开发与部署的关键。本文将详细介绍两种主要的环境变量配置方法:推荐使用的`.env`文件,以及通过`cross-env`库在命令行中设置环境变量。通过这些方法,开发者可以轻松实现开发、测试、生产等不同环境下配置的动态切换,提高应用的可维护…

    2025年12月6日 web前端
    000
  • 环境搭建docker环境下如何快速部署mysql集群

    使用Docker Compose部署MySQL主从集群,通过配置文件设置server-id和binlog,编写docker-compose.yml定义主从服务并组网,启动后创建复制用户并配置主从连接,最后验证数据同步是否正常。 在Docker环境下快速部署MySQL集群,关键在于合理使用Docker…

    2025年12月6日 数据库
    000
  • Xbox删忍龙美女角色 斯宾塞致敬板垣伴信被喷太虚伪

    近日,海外游戏推主@HaileyEira公开发表言论,批评Xbox负责人菲尔·斯宾塞不配向已故的《死或生》与《忍者龙剑传》系列之父板垣伴信致敬。她指出,Xbox并未真正尊重这位传奇制作人的创作遗产,反而在宣传相关作品时对内容进行了审查和删减。 所涉游戏为年初推出的《忍者龙剑传2:黑之章》,该作采用虚…

    2025年12月6日 游戏教程
    000
  • 如何在mysql中分析索引未命中问题

    答案是通过EXPLAIN分析执行计划,检查索引使用情况,优化WHERE条件写法,避免索引失效,结合慢查询日志定位问题SQL,并根据查询模式合理设计索引。 当 MySQL 查询性能下降,很可能是索引未命中导致的。要分析这类问题,核心是理解查询执行计划、检查索引设计是否合理,并结合实际数据访问模式进行优…

    2025年12月6日 数据库
    000
  • VSCode入门:基础配置与插件推荐

    刚用VSCode,别急着装一堆东西。先把基础设好,再按需求加插件,效率高还不卡。核心就三步:界面顺手、主题舒服、功能够用。 设置中文和常用界面 打开软件,左边活动栏有五个图标,点最下面那个“扩展”。搜索“Chinese”,装上官方出的“Chinese (Simplified) Language Pa…

    2025年12月6日 开发工具
    000
  • VSCode性能分析与瓶颈诊断技术

    首先通过资源监控定位异常进程,再利用开发者工具分析性能瓶颈,结合禁用扩展、优化语言服务器配置及项目设置,可有效解决VSCode卡顿问题。 VSCode作为主流的代码编辑器,虽然轻量高效,但在处理大型项目或配置复杂扩展时可能出现卡顿、响应延迟等问题。要解决这些性能问题,需要系统性地进行性能分析与瓶颈诊…

    2025年12月6日 开发工具
    000
  • php查询代码怎么写_php数据库查询语句编写技巧与实例

    在PHP中进行数据库查询,最常用的方式是使用MySQLi或PDO扩展连接MySQL数据库。下面介绍基本的查询代码写法、编写技巧以及实用示例,帮助你高效安全地操作数据库。 1. 使用MySQLi进行查询(面向对象方式) 这是较为推荐的方式,适合大多数中小型项目。 // 创建连接$host = ‘loc…

    2025年12月6日 后端开发
    000
  • 如何在mysql中定期清理过期备份文件

    通过Shell脚本结合cron定时任务实现MySQL过期备份文件自动清理,首先统一备份命名格式(如backup_20250405.sql)并存放在指定目录(/data/backup/mysql),然后编写脚本使用find命令删除7天前的.sql文件,配置每日凌晨2点执行的cron任务,并加入日志记录…

    2025年12月6日 数据库
    000

发表回复

登录后才能评论
关注微信