python TCP 多线程收发信息

前言

很久没写博客了呢。这次是要用 python 实现一个简单的 TCP 客户端,在主线程中发送信息,然后子线程中接收信息,这样就不会因为 socket 接收信息的阻塞而影响速度了。

环境

  • win10 1909
  • python 3.7.5

程序实现

不说废话了,直接把程序贴上来吧~

import time
import socket
import threading

socket_flag = False
socket_msg = ""
clientSocket = None


def SocketReceive(clientSocket):
    ''' Socket 接收线程。'''
    global socket_flag, socket_msg  # 通过全局变量,让外部可以控制线程的运行,也可以处理信息
    while socket_flag:
        try:
            recvData = clientSocket.recv(64)
        except socket.timeout:  # 忽视掉超时
            continue
        if len(recvData) > 0:
            socket_msg = recvData.decode()  # 将接收到的字节数据转为 string
            print("Socket receive: " + socket_msg)
    clientSocket.close()
    print("Client closed.")


if __name__ == '__main__':
    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    address = ('127.0.0.1', 8080)
    serverSocket.bind(address)  # 绑定地址
    serverSocket.listen(2)  # 监听最多两个客户端(虽然我只计划连进来一个)
    # 连接外部客户端,并设置超时
    print("Waiting a client...")
    clientSocket, destAddr = serverSocket.accept()
    clientSocket.settimeout(5)  # 单位:秒
    print("Client connected.")

    try:
        # 启动线程
        socket_flag = True
        t2 = threading.Thread(target=SocketReceive, args=(clientSocket, ))
        t2.start()
        # 在主线程中执行发送任务
        count = 10
        while count:
            clientSocket.send(b'3')
            count -= 1
            time.sleep(1.5)
        clientSocket.send(b'---------')
        print("Sending complete.")
        socket_flag = False
        t2.join()  # 此处等待子线程完结,并关闭客户端连接
        serverSocket.close()
        print("Done.")

    except Exception as e:
        print("Error: ", e)

运行结果

用 socket 调试工具,在回环地址 127.0.0.1 中测试如下:
在这里插入图片描述
主线程一直在进行发送直到达到次数,中途也可以接受客户端传来的数据信息,并且程序完成后能够正常退出。

小结

程序蛮简单的,主要是被 socket 的阻塞搞得有点烦,用这种方式就可以正常退出程序了。不过,这个方法只是打算解决服务器先于客户端关闭的情况。如果系统设计中,客户端先退出,则不需要设置 timeout,可以把线程改为如下形式

def SocketReceive(clientSocket):
    ''' Socket 接收线程。'''
    global socket_flag, socket_msg  # 通过全局变量,让外部可以控制线程的运行,也可以处理信息
    while socket_flag:
        recvData = clientSocket.recv(64)
        if len(recvData) > 0:
            socket_msg = recvData.decode()  # 将接收到的字节数据转为 string
            print("Socket receive: " + socket_msg)
        else:  # 阻塞状态下如果能运行到这里就说明客户端关闭了。
            break
    clientSocket.close()
    print("Client closed.")
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页