基于Python的网络编程(TCP)

本文介绍了一个基于Python3.7的TCP客户端与服务器实现,包括自动重连、心跳检测、多线程并发处理等功能。客户端采用类封装,实现发送、接收接口,支持多行数据交互。服务器用于测试客户端的有效性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个TCP的小程序,把Client做成了一个类,实现了Client、Server,发送、接收接口(可发送和接收多行数据),自动重连,心跳检测,python多线程实现同时执行两个while循环,主要是对网上方法的整合和改进。此程序基于Python 3.7。

Client:

  1. 发送接口的实现,net_is_ok用来判断当前是否与Server连接,只有连接状态才能发送数据:
  2. 接收接口的实现,通过引入尾标识End来实现接收多行数据(这些数据以End结尾),这里引用了https://www.cnblogs.com/litaozijin/p/6624029.html 的方法,recv方法本身可以保持长连接(具体请看文档),所以一旦Server关闭导致连接中断,会触发socket.error,然后在except里面调用连接方法,实现自动重连
  3. 自动重连的实现,因为不知道怎么退出while True方法,就用了一个flag来表示网络连接与否,算是一个笨方法了。
  4. python多线程实现同时执行两个while循环,困扰了我好久,看这里照着写的https://www.cnblogs.com/zoro-robin/p/6117135.html,注意多线程调用的两个方法后面要加上time.sleep(1)来让另一个线程有运行的机会 
  5. 心跳检测,说明在下面都有注释了,这里Client和Server里面用的是两种不一样的,作用差不多,只是一个可修改参数,一个不可以,感觉对这个心跳检测的应用还是不很理解,都有recv()来判断连接状态了,还需要心跳检测吗?

话不多说,代码如下:

#!/usr/bin/python3
# 文件名:client.py

# 导入 socket模块
import socket
import time
import threading


class Client:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    net_is_ok = True

    # 初始化
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.s = self.do_connect(self.host, self.port)

        # 心跳检测,1表示启动,后面两个分别表示检测开始时间和间隔,单位为毫秒
        self.s.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 10000, 3000))

    # 自动重连
    def do_connect(self, host, port):
        self.net_is_ok = False
        # 创建 socket 对象
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        while not self.net_is_ok:
            try:
                # 连接服务,指定主机和端口
                sock.connect((host, port))
                self.net_is_ok = True
            except socket.error:
                print('\n网络错误,开始重连')
                time.sleep(3)
        return sock

    # 发送接口
    def send_msg(self):
        while True:
            if self.net_is_ok:
                print("\n请输入你想发送的数据,回车结束:")
                # hello = 'Hello' + "\r\n"
                hello = input('>>')
                hello = hello + "\r\n"
                self.s.send(hello.encode())
            time.sleep(1)

    # 接收接口
    def receiver_msg(self):
        End = r'\r\n'
        while True:
            try:
                # 接收小于 1024 字节的数据
                # 读取接收到的数据并写入文件
                total_data = []
                print("\nClient读入数据准备")
                while True:
                    # 对于接收到的数据要用decode()把utf-8解码转成unicode编码
                    data = self.s.recv(1024).decode()
                    # 收到End表明接收数据完成
                    if End in data:
                        total_data.append(data[:data.find(End)])
                        break
                    total_data.append(data)
                print("\nClient开始写入文件")
                data = ''.join(total_data)  # join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
                # 文件要与程序文件放在一个目录下
                with open('Client.txt', 'a') as f:
                    f.write(data)

            except socket.error:
                # 自动重连
                self.s = self.do_connect(self.host, self.port)

            except IOError:
                print('\n写入文件错误')

            # except:
            #     print('\n其他错误发生')
            time.sleep(1)

    # 多线程调用
    def my_thread(self, name):
        if name == 'send':
            self.send_msg()
        else:
            if name == 'recv':
                self.receiver_msg()
            else:
                print('error: The format is not recognized!')

然后就是调用类名和函数并给参数就可以了

Server:

因为就是用来测试Client是否有效的,所以基本就参考着菜鸟教程写的,只是根据需要改动了不重要的地方。

有需要看完整例子的可以点这里下载

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值