【TCP 网络通信(发送端 + 接收端)实例 —— Python】

TCP 网络通信(发送端 + 接收端)实例 —— Python

  • 1. 引言
  • 2. 创建 TCP 服务器(接收端)
    • 2.1 代码示例:TCP 服务器
    • 2.2 代码解释:
  • 3. 创建 TCP 客户端(发送端)
    • 3.1 代码示例:TCP 客户端
    • 3.2 代码解释:
  • 4. 运行示例
  • 5. 异步 TCP 通信
    • 5.1 异步 TCP 服务器
    • 5.2异步 TCP 客户端
    • 5.3 代码解释:
  • 6. 总结
  • 7. 常见问题解答
  • 8. 参考资料

1. 引言

在这里插入图片描述

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它广泛应用于互联网和局域网中,确保数据能够安全、有序地从一个设备传输到另一个设备。本文将通过具体的 Python 实例,详细介绍如何实现 TCP 网络通信中的发送端和接收端。

  1. NetAssist网络调试助手
  2. Python环境配置

准备工作

在开始编写代码之前,确保您已经安装了 Python 环境。Python 内置的 socket
模块提供了对低级网络接口的访问,因此不需要额外安装任何库。


2. 创建 TCP 服务器(接收端)

服务器端的主要任务是监听来自客户端的连接请求,并与每个连接的客户端进行双向通信。我们将使用多线程来处理多个客户端的并发连接。

2.1 代码示例:TCP 服务器


import socket
import threading
import queue
import time# 定义服务器地址和端口
HOST = '192.168.1.111'  # 本地回环地址
PORT = 8080        # 非特权端口# 全局消息队列,用于存储服务器要发送的消息
message_queue = queue.Queue()# 线程安全的客户端列表,存储所有已连接的客户端套接字
clients = set()# 锁对象,确保对 clients 集合的操作是线程安全的
lock = threading.Lock()def handle_client(client_socket, client_address):print(f"Connected by {client_address}")try:while True:# 接收来自客户端的数据data = client_socket.recv(1024)if not data:break  # 如果没有收到数据,退出循环print(f"Received from {client_address}: {data.decode()}")# 发送响应给客户端response = f"Server received: {data.decode()}"client_socket.sendall(response.encode())# 模拟服务器主动发送数据time.sleep(5)  # 每隔5秒检查是否有新消息with lock:if not message_queue.empty():msg = message_queue.get()print(f"Sending to {client_address}: {msg}")client_socket.sendall(msg.encode())except Exception as e:print(f"Error handling client {client_address}: {e}")finally:# 关闭客户端连接with lock:clients.discard(client_socket)client_socket.close()print(f"Connection with {client_address} closed.")def broadcast_message(message):"""将消息发送给所有已连接的客户端"""with lock:for client in clients:try:client.sendall(message.encode())except Exception as e:print(f"Failed to send message to client: {e}")def start_server():with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:server_socket.bind((HOST, PORT))server_socket.listen()print(f"Server listening on {HOST}:{PORT}")# 启动一个后台线程,定期检查消息队列并广播消息threading.Thread(target=check_and_broadcast_messages, daemon=True).start()while True:client_socket, client_address = server_socket.accept()with lock:clients.add(client_socket)# 为每个新连接启动一个新的线程来处理client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))client_thread.start()def check_and_broadcast_messages():"""定期检查消息队列并广播消息"""while True:if not message_queue.empty():msg = message_queue.get()print(f"Broadcasting message: {msg}")broadcast_message(msg)time.sleep(1)  # 每隔1秒检查一次if __name__ == "__main__":# 启动服务器threading.Thread(target=start_server, daemon=True).start()# 模拟服务器主动发送消息while True:msg = input("Enter message to broadcast (or type 'exit' to quit): ")if msg.lower() == 'exit':breakmessage_queue.put(msg)

2.2 代码解释:

  • server_socket.bind():绑定服务器到指定的 IP 地址和端口。
  • server_socket.listen():使服务器进入监听状态,等待客户端连接。
  • server_socket.accept():接受一个客户端连接,返回一个新的套接字对象和客户端地址。
  • handle_client():处理客户端的通信,接收数据并回显给客户端。
  • threading.Thread():为每个新连接启动一个新的线程,以便服务器可以同时处理多个客户端。

运行服务端
在这里插入图片描述

客户端响应,发送body1,正常回传。🤞🤞🤞
在这里插入图片描述

3. 创建 TCP 客户端(发送端)

客户端的主要任务是连接到服务器,并与服务器进行双向通信。客户端可以发送消息给服务器,并接收服务器的响应。

3.1 代码示例:TCP 客户端

import socket
import threading# 定义服务器地址和端口
HOST = '192.168.1.101'  # 本地回环地址
PORT = 8080        # 非特权端口client_socket = Nonedef receive_messages():global client_socketwhile True:try:# 接收服务器的响应response = client_socket.recv(1024).decode()if not response:breakprint(f"Received from server: {response}")except Exception as e:print(f"Error receiving message: {e}")breakdef start_client():global client_socketclient_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client_socket.connect((HOST, PORT))print(f"Connected to server at {HOST}:{PORT}")# 启动一个线程来接收消息receive_thread = threading.Thread(target=receive_messages)receive_thread.daemon = True  # 设置为守护线程,主程序退出时自动结束receive_thread.start()while True:# 输入要发送的消息message = input("Enter message to send (or type 'exit' to quit): ")if message.lower() == 'exit':break# 发送消息给服务器client_socket.sendall(message.encode())client_socket.close()if __name__ == "__main__":start_client()

3.2 代码解释:

  • client_socket.connect():连接到指定的服务器地址和端口。
  • client_socket.sendall():发送数据到服务器。
  • client_socket.recv():接收来自服务器的数据。
  • input():从用户输入获取要发送的消息,用户可以输入 exit 来终止程序。

4. 运行示例

  1. 启动服务器

    • 打开一个终端或命令提示符窗口,导航到包含服务器代码的文件夹,然后运行以下命令:
      python tcp_server.py
      
    • 服务器将开始监听指定的端口,并等待客户端连接。
  2. 启动客户端

    • 打开另一个终端或命令提示符窗口,导航到包含客户端代码的文件夹,然后运行以下命令:
      python tcp_client.py
      
    • 客户端将连接到服务器,并允许用户输入消息发送给服务器。
  3. 测试通信

    • 在客户端窗口中输入消息,按回车键发送给服务器。
    • 服务器将接收消息并回显给客户端,客户端会显示服务器的响应。
    • 用户可以继续发送消息,或者输入 exit 来终止程序。
      在这里插入图片描述

服务端接收:
在这里插入图片描述

这个只能一发一收,不能连续发或连续收,接下来采用异步就可以实现这个缺陷,而且响应更好


5. 异步 TCP 通信

为了提高性能和响应速度,您可以使用 Python 的 asyncio 库来实现异步 TCP 通信。异步编程模型允许程序在等待 I/O 操作时执行其他任务,从而提高效率。

5.1 异步 TCP 服务器

我们将创建一个异步 UDP 服务器,它不仅可以接收来自客户端的数据包并回显,还可以主动向客户端发送消息。服务器将维护一个客户端列表,并定期检查是否有新消息需要发送给所有已连接的客户端。

import asyncio# 定义服务器地址和端口
HOST = '192.168.1.111'  # 本地回环地址
PORT = 8080        # 非特权端口client_address = Noneasync def handle_client(reader, writer):global client_addressdata = await reader.read(1024)addr = writer.get_extra_info('peername')client_address = addr  # 更新全局的 client_addressprint(f"Received from {addr}: {data.decode()}")# 发送响应给客户端response = f"Server received: {data.decode()}"writer.write(response.encode())await writer.drain()print(f"Sent to {addr}: {response}")async def start_server():server = await asyncio.start_server(handle_client, HOST, PORT)addr = server.sockets[0].getsockname()print(f"Server listening on {addr[0]}:{addr[1]}")async with server:await server.serve_forever()async def broadcast_message():while True:msg = await asyncio.to_thread(input, "Enter message to broadcast (or type 'exit' to quit): ")if msg.lower() == 'exit':breakif client_address is not None:  # 确保 client_address 已经被设置try:_, writer = await asyncio.open_connection(*client_address)writer.write(msg.encode())await writer.drain()writer.close()await writer.wait_closed()except ConnectionRefusedError:print("Client is not available.")else:print("No client connected yet.")async def main():# 启动服务器server_task = asyncio.create_task(start_server())# 启动广播消息任务broadcast_task = asyncio.create_task(broadcast_message())await asyncio.gather(server_task, broadcast_task)if __name__ == "__main__":asyncio.run(main())

5.2异步 TCP 客户端

import asyncio# 定义服务器地址和端口
HOST = '192.168.1.101'  # 本地回环地址
PORT = 8080        # 非特权端口async def receive_messages(reader):while True:try:# 接收服务器的响应response = await reader.read(1024)if not response:breakprint(f"Received from server: {response.decode()}")except Exception as e:print(f"Error receiving message: {e}")breakasync def send_messages(writer):while True:# 输入要发送的消息message = await asyncio.get_event_loop().run_in_executor(None, input, "Enter message to send (or type 'exit' to quit): ")if message.lower() == 'exit':break# 发送消息给服务器writer.write(message.encode())await writer.drain()async def start_client():reader, writer = await asyncio.open_connection(HOST, PORT)print(f"Connected to server at {HOST}:{PORT}")# 启动两个任务:一个用于接收消息,一个用于发送消息receive_task = asyncio.create_task(receive_messages(reader))send_task = asyncio.create_task(send_messages(writer))# 等待任一任务完成(即用户输入 'exit' 或连接断开)done, pending = await asyncio.wait([receive_task, send_task], return_when=asyncio.FIRST_COMPLETED)# 取消所有未完成的任务for task in pending:task.cancel()try:await taskexcept asyncio.CancelledError:passwriter.close()await writer.wait_closed()if __name__ == "__main__":asyncio.run(start_client())

5.3 代码解释:

  • asyncio.Protocol:定义了一个异步协议类,用于处理客户端连接。
  • asyncio.open_connection():异步打开与服务器的连接。
  • asyncio.run():启动异步事件循环并运行主函数。
  • 只能输入英文,暂不支持中文

6. 总结

通过上述示例,我们展示了如何使用 Python 实现 TCP 网络通信中的发送端和接收端。同步版本的代码简单易懂,适合初学者;而异步版本则提供了更高的性能和更好的并发处理能力,适用于更复杂的应用场景。🛹🛹🛹


7. 常见问题解答

  • Q: 如何处理多个客户端的并发连接?

    • A: 使用多线程或多进程可以处理多个客户端的并发连接。对于更高效的方式,建议使用 asyncio 库来实现异步编程。
  • Q: 如何确保数据传输的可靠性?

    • A: TCP 协议本身就是一个面向连接的可靠协议,它会自动处理数据包的丢失、重复和乱序问题。此外,您可以在应用层添加更多的错误检测机制,如校验和或消息确认。
  • Q: 如何处理大文件传输?

    • A: 对于大文件传输,建议将文件分块发送,并在每次发送后等待服务器的确认。这样可以确保每一块数据都成功传输,并且可以在出现问题时重新发送。

8. 参考资料

  • Python 官方文档 - socket 模块
  • Python 官方文档 - asyncio 模块
  • TCP/IP 协议详解

从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

  1. 我会持续更新对应专栏博客,非常期待你的三连!!!🎉🎉🎉
  2. 如果鹏鹏有哪里说的不妥,还请大佬多多评论指教!!!👍👍👍
  3. 下面有我的🐧🐧🐧群推广,欢迎志同道合的朋友们加入,期待与你的思维碰撞😘😘😘

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

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

相关文章

day08 接口测试(3)——postman工具使用

下载 postman 的历史版本:Postman 历史版本下载 - 简书 今天开始学习 postman 这个测试工具啦。 【没有所谓的运气🍬,只有绝对的努力✊】 目录 1、postman简介 2、postman的安装 3、给postman安装插件——newman 3.1 环境安装 3.1.1 安…

README写作技巧

做一个项目,首先第一眼看上去要美观,这样才有看下去的动力。做项目亦是如此,如果每一步应付做的话,我想动力也不会太大,最终很大概率会放弃或者进度缓慢。 1.README组成 README是对项目的一个说明,它对观看…

渗透测试---burpsuite(5)web网页端抓包与APP渗透测试

声明:学习素材来自b站up【泷羽Sec】,侵删,若阅读过程中有相关方面的不足,还请指正,本文只做相关技术分享,切莫从事违法等相关行为,本人与泷羽sec团队一律不承担一切后果 视频地址:泷羽---bp&…

【Springboot3+vue3】从零到一搭建Springboot3+vue3前后端分离项目之前端环境搭建

【Springboot3vue3】从零到一搭建Springboot3vue3前后端分离项目之前端环境搭建 2 前端环境搭建2.1 环境准备2.2 创建Vue3项目2.3 项目搭建准备2.4 安装Element Plus2.5 安装axios2.5.1 配置(创建实例,配置请求,响应拦截器)2.5.2 …

11.27-12.5谷粒商城

目录 新增商品 1.上线会员服务 2. 获取分类关联的品牌 3.获取选定分类下的属性分组和属性 4.新增商品vo 5.保存商品信息 6.Spu检索 7.Sku商品检索 新增商品 1.上线会员服务 将会员服务注册到nacos注册中心,启用服务注册发现EnableDiscoveryClient。 同时新增…

深入解析非桥PCI设备的访问和配置方法

往期内容 本文章相关专栏往期内容,PCI/PCIe子系统专栏: 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入 Uart子系统专栏: 专栏地址:Uart子系统 Linux内核早期打印机制与RS485通信技术 – 末片,有专栏内容观看…

ArrayList常见操作源码逐句剖析

目录 前言 正文 1.需要了解的一些字段属性 1.存储 ArrayList 元素的数组缓冲区。 2.集合的大小 3.默认集合容量大小 2.ArrayList对象创建 1.无参构造 2.有参构造1 3.有参构造2 3.添加元素add(E e)以及扩容机制 ​编辑 后言 前言 源码的剖析有助于理解设计模式&…

现代密码学|Rabin密码体制及其数学基础 | 椭圆曲线密码体制及其运算 | DH密钥交换及中间人攻击

文章目录 参考Rabin密码体制及其数学基础中国剩余定理二次剩余Rabin密码体制实例 椭圆曲线密码体制及其运算原理运算规则加密解密实例 DH密钥交换及中间人攻击中间人攻击 参考 现代密码学|Rabin密码体制及其数学基础 现代密码学|椭圆曲线密码体制及其运…

硬件选型规则

光源选型: 先用型号中带H的,没有的选标准的. 光源和光源控制器的搭配需要确保接口一致。 根据型号表中的最佳工作距离和相机的尺寸。 光源控制器选型: 首先选择海康风格系列光源控制器考虑与光源的接口匹配。功率应该满足接近光源功率。检查是否退市…

sharedPreference包的使用总结

文章目录 1 概念介绍2 实现方法3 示例代码我们在上一章回中介绍了"如何自定义评分条"相关的内容,本章回中将介绍如何实现本地存储.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 Flutter是一套跨平台的UI框架,它不像原生SDK一样提供本地存储功能,因此,我们在…

TCP连接的时候遇到的异常(目标端口没开放)

import asyncioasync def check_port(ip, port, timeout1):"""检查目标 IP 和端口是否开放:param ip: 目标 IP 地址:param port: 目标端口:param timeout: 超时时间(秒)"""try:reader, writer await asyncio.open_connec…

C总结(C语言知识点,深化重难点)

C语言 1.使用C语言的7个步骤2.ASCII码3.提高程序可读性的机巧4.如何使用多种整形5.打印多种整形6.课移植类型:stdint.h和inttypes.h7.浮点数常量8.浮点值的上溢和下溢9.使用数据类型11.常量和C预处理器12.转换说明的意义12.1转换不匹配13.副作用和序列点14.数组简介…

burpsuite(6)暴力破解与验证码识别绕过

声明!!! 学习视频来自B站UP主泷羽sec,如涉及侵权马上删除文章 视频链接:泷羽sec-bilibili 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 项目地址:https://github.com/f0ng/cap…

抗DDOS设备

0x00 定义: 抗DDOS设备顾名思义,就是防御DDoS攻击的设备,通常包含三个部分:检测中心、清洗中心和管理中心 检测中心主要负责对流量进行检测,发现流量异常后上报管理中心,由管理中心下发引流策略至清洗中心&#xff0…

systemV信号量与消息队列

目录 引言 ipc简介 ipc在kernel的管理机制(简介) 信号量 理解信号量 原子 结论 mmap 消息队列 接口 引言 在复杂的软件系统中,进程间的协调和通信是确保系统高效、稳定运行的关键。System V是一套历史悠久且功能强大的进程间通信&a…

【CKS最新模拟真题】Falco 的运行时安全性

系列文章目录 【CKS最新模拟真题】获取多个集群的上下文名称并保存到指定文件中 文章目录 系列文章目录参考地址一、TASK二、解题过程1、问题一解题2、问题二解题 参考地址 CKS考试允许打开falco的地址 https://falco.org/docs/reference/rules/supported-fields/ 一、TASK …

Altium Designer学习笔记 32 DRC检查_丝印调整

基于Altium Designer 23学习版,四层板智能小车PCB 更多AD学习笔记:Altium Designer学习笔记 1-5 工程创建_元件库创建Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制Altium Designer学习笔记 11-15 原理图的封装 编译 检查 _PCB封装库的创建Al…

【原生js案例】webApp实现鼠标移入移出相册放大缩小动画

图片相册这种动画效果也很常见,在我们的网站上。鼠标滑入放大图片,滑出就恢复原来的大小。现在我们使用运动定时器来实现这种滑动效果。 感兴趣的可以关注下我的系列课程【webApp之h5端实战】,里面有大量的css3动画效果制作原生知识分析&…

MetaGPT 安装

1. 创建环境 conda create -n metagpt python3.10 && conda activate metagpt2. 可编辑方式安装 git clone --depth 1 https://github.com/geekan/MetaGPT.git cd MetaGPT pip install -e .3. 配置 metagpt --init-config运行命令,在C盘位置C:\Users\325…

流量地球(Java Python JS C++ C )

题目描述 流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。 初始状态下所有的发动机都是未启动状态;发动机启动的方式分为”手动启动"和”关联启动"两种方式;如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被”关联启动”…