网口程序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是一样的,因为都在一台电脑上.

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



posted @ 2020-12-28 20:09  GXTon  阅读(269)  评论(0编辑  收藏  举报