• 网口程序udp


    # -*- coding: utf-8 -*-
    """
    Created on Thu Nov 12 15:02:53 2020
    
    @author: Administrator
    
    参考网址:https://www.pianshen.com/article/1060421464/
    https://blog.csdn.net/qq_40483425/article/details/105475678
    """
    
    import socket
    import threading
    import time
    
    
    def recv_msg(udp_socket):
        """接收"""
        while True:
            recv_data = udp_socket.recvfrom(1024)
            print("%s 发送 %s" % (str(recv_data[1]), recv_data[0].decode("gbk")))
    
    
    def send_msg(udp_socket, dest_ip, dest_port):
        """发送"""
        while True:
            send_data = "haha"
            udp_socket.sendto(send_data.encode("gbk"), (dest_ip, dest_port))
            time.sleep(1) 
    
    
    def main():
        # 创建套接字
        udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
        # 绑定本地信息
        udp_socket.bind(("", 7890))
    
        # 获取对方信息
        dest_ip = "192.168.43.216"
        dest_port = 1234
    
        # 创建两个线程去执行函数
        t1 = threading.Thread(target=recv_msg, args=(udp_socket, ))
        t2 = threading.Thread(target=send_msg, args=(udp_socket, dest_ip, dest_port))
    
        t1.start()
        t2.start()    
        #要有下面的join,否则会运行不完一个线程,就会跳到另一个线程.
        t1.join()
        t2.join()
    
    if __name__ == '__main__':
        main()

    上面这个程序是可以运行的,下面是运行效果

    要让Python可以进行收发.

    为了防止冲突,把网络助手设置成如下:

     如上图,网络助手可以看做一台电脑,它自己的地址是192.168.43.216 端口号是2345 

    网络助手要发送给: 192.168.43.216 端口号1234

    其实两个地址是一样的,就是端口号不同.

    把Python编写的,软件,自身的地址 192.168.43.216 端口号 1234

    要发送给,192.168.43.216. 端口号2345  (就是网络助手)

    然后用下面代码:

    '''
    这里是关于udp的逻辑实现部分
    也就是这里只是upd的各种动作,但是调用这些动作是在main中进行的.
    udp是用户数据传输协议,位域TCP/IP协议的传输层.是一种无连接的协议.它发送的报文不能确定是否完整地到达另一端.
    
    
    [需要做] 怎么实现的界面和逻辑分离, 逻辑如何和界面进行交互. 应该是在main函数里面了
    [需要做] 关于Python中类的实现.需要好好弄明白语法.
    [需要做] 关于try的用法.
    [需要做] 关于socket的用法:https://www.cnblogs.com/nevermore29/p/9592080.html
    [需要做] 这里接收数据,创建了一个线程,但是发送数据,并没有创造线程.
    [需要做] 修饰器怎么从别的文档引入进来.???
    [需要做] 要让udp的那个按钮选一个,开两个进程,就是能用udp发和收.
    
    [心得] socket就是针对服务器,客户端进行  打开-->读写-->关闭  的一系列操作.
    [心得] https://blog.csdn.net/qq_41262248/article/details/80791000
           ip:绑定了电脑; 一个电脑一个ip
           端口号:绑定了程序进程; 软件中不同的网口进程,有不同的端口号;  端口号范围0-65536 知名端口号0-1024和动态端口号   80端口网站:http
           局域网中不能有两个相同的ip地址.
    '''
    
    
    
    
    
    import time
    from PyQt5 import QtWidgets
    import net_stopThreading
    import socket
    import threading                              #这里是线程吗是的.
    import sys
    from write_txt import write_txt
    from net_time_xh  import fn_timer                 #这个修饰器怎么从别的文档引入.确实是这样,可以这样进行引用了.
    
    
    
    from ui_demo_6 import Ui_Form                #这里是界面
            
    
    
    
    #下面这里就是一个网口的类
    #里面包含了网口的各种操作
    #这里是一个类,然后继承了界面的类
    #没有槽函数,关于槽函数的逻辑,都是在主函数那里实现的
    class UdpLogic(Ui_Form):       
        def __init__(self):
            super(UdpLogic, self).__init__()
            pass
    
        #这里是选中udp标签之后,就会执行这里.
        #主函数里面会调用这个函数.
        def udp_start(self):               
            """
            这个是打开服务器,然后服务器只是负责接收.
            开启UDP服务端方法
            单片机是客户端.
            :return:
            """
            #创建udp对象
            self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)     #等号后面调用是固定的  创建socket对象,名字是udp_socket  创建udp
            #本地的ip和端口
            #返回里面的文字,返回本地端口号
            #self.local_port=self.net_box_local_portnumber.currentText()
            #self.local_port = int(self.local_port)
            
            
    #        self.object_port=self.net_box_object_portnumber.currentText()      
    #        self.local_IP=self.net_box_local_IP.currentText()
    #        self.object_IP=self.net_box_object_IP.currentText() 
    #        print('udp_start',"本地端口号:",self.local_port)   
    #        print("udp_start","对方端口号:",self.object_port)
    #        print('udp_start',"本地IP:",self.local_IP)   
    #        print("udp_start","对方IP:",self.object_IP) 
            
    
            #测试
            self.object_IP= "192.168.43.216"
            self.local_IP = "192.168.43.216"
            self.object_port =2345
            self.local_port=1234
            
    
               
            #gxt先固定端口号
            address = ('', self.local_port)
            self.udp_socket.bind(address)                                          #[注意这里,进行了绑定,那么端口号就是固定的了]绑定地址,address取决于地址族.  这里的address是元组比如:('127.0.0.1',8080)  
         
            print("开始创建线程了")                                                      #try中没有出现异常情况.
            self.sever_th = threading.Thread(target=self.udp_receive)        #这里是创造一个线程.  注意这里的括号里面,里面是udp_server_concurrency这是一个函数.
            self.send_th = threading.Thread(target=self.udp_send)                       #这里是创造一个线程.  注意这里的括号里面,里面是udp_server_concurrency这是一个函数.
            self.sever_th.start()                                                       #开启线程.   为什么没有加入那个东西.
            self.send_th.start() 
            self.sever_th.join()
            self.send_th.join()
            #奇怪,下面这句话输出不了???
            print("线程创建完毕")        
            
        ################################################################################################################################################################################
        ###############################  接收数据 ###################################
        #读网口会写这个缓存,写txt也会用到这个缓存,这里是不是两个进程都会用到一个内存,所以就是需要用到信号量??
        def udp_receive(self):
            """
            这里是udp的接收.
            用于创建一个线程持续监听UDP通信
            有个疑问?? 开启了这里的线程,那么这个while就会一直执行下去吗???
            """
            while True:
                print("udp_receive","网口正在接收...")
                #time.sleep(1)  #这里是停止1秒
                #有个疑问?这里定义的变量,应该是属于全局变量的,
                #然后怎么在其他文档中用到这个变量.
                self.recv_msg, self.recv_addr = self.udp_socket.recvfrom(1024)                    #这里的参数是从缓冲区度1024字节的数据 接收udp套接字的数据. 返回的是data,address. 其中data是包含接收数据的字符串,address是发送数据的套接字的地址.
                print("%s 接收 %s" % (str(self.recv_addr), self.recv_msg.decode("gbk")))          #这里要注意,window用的是gbk
                
                #gxt
                #有待完善???
                #write_txt(msg)                                                          #这里还是可以优化的.
                
                #返回里面的文字,返回本地端口号
        #            self.local_port=self.net_box_local_portnumber.currentText()
        #            self.object_port=self.net_box_object_portnumber.currentText()
        #            
        #            self.local_IP=self.net_box_local_IP.currentText()
        #            self.object_IP=self.net_box_object_IP.currentText()            
                
                #把接收的msg,显示到窗口处
                #有待完善:
                #self.s2__receive_text.emit(msg)                                         #这个是信号   用于显示在接收界面中的.  这里是通过这个刷新ui界面显示的.
    
                
                
    
        #########################################网口发送数据#############################################
        #################################################################################################
        #这里发送有个问题,端口号总是在改变
        #主函数会调用这个.
        def udp_send(self):
            """
            这里是udp的发送
            功能函数,用于UDP客户端发送消息
            :return: None
            """
            while(1):
                #print("切换到网口发送...")
                time.sleep(1)
                # 获取对方信息
                
        #        #返回里面的文字,返回本地端口号
        #        self.local_port=self.net_box_local_portnumber.currentText()
        #        self.object_port=self.net_box_object_portnumber.currentText()
        #        #注意!!!从窗口读出来的端口号是字符,必须要转换成数字
        #        self.object_port=int(self.object_port)
        #        self.local_IP=self.net_box_local_IP.currentText()
        #        self.object_IP=self.net_box_object_IP.currentText() 
        #        send_msg = (str(self.s3__send_text.toPlainText())).encode("gbk") 
                
                
                send_msg="haha"
                self.udp_socket.sendto(send_msg.encode("gbk"), (self.object_IP, self.object_port))
                #有待完善
                #self.s2__receive_text.emit(msg)        
    
                    
    
        #下面是关闭udp的.
        def udp_close(self):
            """
            功能函数,关闭网络连接的方法.
            分别代表了关闭服务器和客户端.
            :return:
            """
            try:
                self.udp_socket.close()
                if self.link is True:
                    print("已断开网络")
                    #有待完善emit
                    #self.s2__receive_text.emit(msg)
            except Exception as ret:
                ret=ret #防止报警
                pass
    
            try:
                net_stopThreading.stop_thread(self.sever_th)
            except Exception:
                pass
            try:
                net_stopThreading.stop_thread(self.client_th)
            except Exception:
                pass
    
    
    
    
        
        
    if __name__ == '__main__':
        ui=UdpLogic()
        ui.udp_start()
        print("udp")
        pass
    
        
    
        
        
        

    然后运行效果:

     总结:

    你写的软件和 下载的网络助手,

    这个两个软件的ip是一样的,因为都在一台电脑上.

    但是两个软件的端口号是不同的! 因为是两个软件.
        
        



  • 相关阅读:
    使用SuperWebSocket 构建实时 Web 应用
    slam for Windows 库安装及应用libfreenect2
    《SLAM十四讲》g2o_custombundle在windows轻松调通
    windows下命令行查看库依赖
    zend studio控制台中文乱码
    http协议转
    mysql 字段 增删改
    PHP内部函数
    分层设计
    SecureCRT上传和下载
  • 原文地址:https://www.cnblogs.com/chulin/p/14203355.html
Copyright © 2020-2023  润新知