网口程序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是一样的,因为都在一台电脑上.
但是两个软件的端口号是不同的! 因为是两个软件.