串网直通车——网口篇(Python+socket+threading)

         完整代码链接:https://download.csdn.net/download/qq_34162147/54904655        

        本章节是续前篇(界面篇)。如未搭建界面,请查阅以下链接。

        串网直通车——界面篇(Python+Tkinter)_不尽之野火-CSDN博客


        本章节主要是实现网口的UDP功能,实现网口收发数据。类似网络调试助手。

1、打开网口

        Python使用网口功能以及线程功能,需要在开头引入。结合前篇(界面篇),需要在开头引入全局变量。

import socket       #网口
import threading    #线程


global udp_socket
global opposite_addr
global net_text
net_state=0
global trans_uc

        将以下代码替换到界面篇的net_ctrl函数。整体替换。

        这个函数中nn_var,lip_var,lp_var,oip_var,op_var,nl_var,p0,p1都是通过按钮操作传递过来,读取下拉菜单的值。

        nn_var是按钮控件名 

        lip_var是本地IP地址

        lp_var是本地端口号

        oip_var是远程IP地址

        op_var是远程端口号

        nl_var是指示灯控件

        p0是红灯图片

        p1是绿灯图片

       函数中,recv_net_data是用来定义接收线程。接收函数是thread_net_recv,后续有讲解。创建线程是为了实现接收一直起作用,程序并与界面显示并行运行。

        代码经过优化,经测试达到0错误。代码中多次使用if和else pass组合。是因为参考其他程序时,发现有错误,无法正常停止网口,端口号一直被占用。而且在else之后绑定网口的udp_socket无法继续使用。如有大神能够知道原因,请在评论区告知,在此感谢!

# 网口打开关闭函数
def  net_ctrl(nn_var,lip_var,lp_var,oip_var,op_var,nl_var,p0,p1):

    global udp_socket
    global opposite_addr
    global net_text
    global net_state
    
    if nn_var.get() == "打开网口":
        # 创建一个UDP套接字
        udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)     
        # 本地ip地址和端口号,这是一个元组,其中ip地址是字符串,端口号是数字
        local_addr = (lip_var, int(lp_var))  
        # 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
        udp_socket.bind(local_addr)
        # 远程ip地址和端口号,这是一个元组,其中ip地址是字符串,端口号是数字
        opposite_addr = (oip_var, int(op_var))  

        net_state=1

        net_text.delete(1.0,END)      
        nl_var.configure(image=p1) 

        recv_net_data = threading.Thread(target=thread_net_recv)#创建接收线程
        recv_net_data.start()

    else :
        pass

    if nn_var.get() == "关闭网口" :
        udp_socket.close()
        net_state=0
        nn_var.set("打开网口")    
        nl_var.configure(image=p0) 
    else:
        pass  



    if (net_state==1) :
        nn_var.set("关闭网口")
        nl_var.configure(image=p1) 
    else:
        pass   

2、接收

        接收函数整体添加即可。这部分对应打开网口的thread_net_recv函数。

        代码中net_text.see(END),see是用于ScrolledText滚动条文本框控件的光标移动,使得滚动条随着接收数据的增多而移动至最后。此部分结合界面篇的带滚动条文本框部分。

        代码中使用了try和except Exception:break的组合,作用在于接收时,防止接收函数recvfrom()导致出错。出错时会有退出机制。其他网上代码存在此部分不完善的地方。这部分导致停止运行时无法正常停止。必须强制关闭运行进程。

        代码中“停止接收线程”备注那部分,作用是点击按钮关闭时,能够跳出线程,并终止。因为接收代码运行时,一直在while循环。其他网上代码存在此部分不完善的地方。必须强制关闭运行进程,否则网口端口号一直出错而占用。

        代码中的decode是解码。

        此部分代码提到的net_send函数,后续会讲解到。只测试接收时,可以先屏蔽。

        特别注意:此部分代码测试时,不能直接点击窗口右上角关闭,必须优先点击关闭网口按钮,关闭窗口。
 

# 网口数据接收线程
def thread_net_recv():
    global net_text
    global net_state
    global trans_uc

    while True:
        try:
            read_net = udp_socket.recvfrom(1024)  # 1024表示本次接收的最大字节数
            trans_uc=read_net[0].decode("utf-8")
            net_text.insert(END,trans_uc)
            net_text.insert(END,'\n')
            net_text.see(END)#滚动条移动到最新输入位置     
            net_send('I have received your data')
            print(read_net,)
            print("UDP 接收到的数据:%s" % trans_uc)
            # addr_ip,addr_port=read_net[1]
            # print("接收到的对方IP地址:%s" % addr_ip)
            # print("接收到的对方端口:%s" % addr_port)
            # net_send('OK')

        except Exception:
            break     

插节

如果程序一直运行,不知道什么错误,如图所示,可以强制停止。我用的是VScode+python3.8。

3、发送

         这部分的代码直接添加即可。此部分结合接收函数使用测试。

        代码中encode是编码。ns_var是字符串,目的地址opposite_addr(IP+端口号)引用之前变量,只引用不改变参数,无需使用global。

def net_send(ns_var):
    udp_socket.sendto(ns_var.encode('utf-8'), opposite_addr)

4、测试

        可用网络调试助手配合从测试。测试效果如图所示。

 5、拓展

        在学习过程,参考了不少资料,也填了不少坑。在此感谢各位前辈们的付出。经过整理筛选后,同样将有用的分享给大家!

python socket recv超时_如何用python实现接收UDP方式的网络通信数据_weixin_39999025的博客-CSDN博客

Python网络通信(1)— UDP通信_Willliam_william的博客-CSDN博客

Python网络通信

https://so.csdn.net/so/search?q=Python%E7%BD%91%E7%BB%9C%E9%80%9A%E4%BF%A1&t=blog&u=qq_38113006

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值