python实现简单的udp发送和接收
作者:qq_278667286
这篇文章主要介绍了python实现简单的udp发送和接收方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
python简单的udp发送和接收
server端
# udp_gb_server.py '''服务端(UDP协议局域网广播)''' import socket,time,struct s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) PORT = 6454 network ='127.0.0.1'# '<broadcast>' s.sendto('Client broadcast message!'.encode('utf-8'), (network, PORT)) def formatdata(dvcid,dat): sendBuf=[0x41, 0x72, 0x74, 0x2D, 0x4E, 0x65, 0x74, 0x00, 0x00, 0x50, 0x00, 0x0E, 0x77, 0x01] #sendBuf[14]设备节点 #sendBuf[15] = 0x00; sendBuf.append(dvcid& 0xff) sendBuf.append(0x00) # 发送的字节数 512 #sendBuf[16] = 0x02; #sendBuf[17] = 0x00; datlen = len(dat) sendBuf.append((datlen & 0xff00) >> 8) sendBuf.append(datlen & 0xff) # 发送的数据 #sendBuf[17+n] = 0x00; print( datlen) for x in range(datlen): pass sendBuf.append((dat[x] & 0xff))#.to_bytes(1,'big') #data = [1, 2, 3] #buffer = struct.pack("!ihb", *data) packstyle=str(18+datlen)+'B'#B 0-255 #req = struct.pack('14b',*sendBuf) 0-127 req = struct.pack(packstyle, *sendBuf) return req import struct from ctypes import create_string_buffer def pack(): # 创建一个9字节大小的缓存区,初始化默认全部为\x00 buf = create_string_buffer(9)# buf.raw: '\x00\x00\x00\x00\x00\x00\x00\x00\x00' # 冲缓存区buf的第0个字节开始打包两个4字节无符号整型数据1和2 struct.pack_into(">II", buf, 0, 1, 2)# buf.raw: '\x00\x00\x00\x01\x00\x00\x00\x02\x00' # 然后我们想再打包一个布尔型数据到buf中就可以改变以下偏移量 struct.pack_into(">?", buf, 8, True)# buf.raw: '\x00\x00\x00\x01\x00\x00\x00\x02\x01' return buf c=0 while True: c=c+1 d=[200,1,2,3,4,5,6,7] #d = [0 for i in range(512)] a= [] for i in range(512): a.append(i)#''' print(a) print(c) #senddata(2,d) req = struct.pack('8B', int('3F', 16), int('20', 16), int('63', 16), int('31', 16), int('0D', 16), int('0A', 16), int('0D', 16), int('0A', 16)) #s.sendto((b"\x78\x78\x11\x01\x07\x52\x53\x36\x78\x90\x02\x42\x70\x00\x32\x01\x00\x05\x12\x79\x0D\x0A"),(network, PORT)) #s.sendto(req, (network, PORT)) s.sendto(formatdata(128,a), (network, PORT)) #s.sendto(pack(), (network, PORT)) time.sleep(1) ''' byte[] sendBuf = new byte[530];//设置发送缓存区 //41 72 74 2D 4E 65 74 00 00 50 00 0E 77 01 //按照协议报文填充数据 //固定格式 sendBuf[0] = 0x41; sendBuf[1] = 0x72; sendBuf[2] = 0x74; sendBuf[3] = 0x2D; sendBuf[4] = 0x4E; sendBuf[5] = 0x65; sendBuf[6] = 0x74; sendBuf[7] = 0x00; sendBuf[8] = 0x00; sendBuf[9] = 0x50; sendBuf[10] = 0x00; sendBuf[11] = 0x0E; sendBuf[12] = 0x77; sendBuf[13] = 0x01; //设备节点 if (Convert.ToInt16(textBox7.Text) > 0 && Convert.ToInt16(textBox7.Text) < 5) { sendBuf[14] = Convert.ToByte(Convert.ToInt16(textBox7.Text)-1); } else { MessageBox.Show("设备节点输入有误"); } sendBuf[15] = 0x00; //发送的字节数 sendBuf[16] = 0x02; sendBuf[17] = 0x00; //后面的字节就是DMX512对应的512个通道的数据了 if (Convert.ToInt16(textBox1.Text) >= 1 && Convert.ToInt16(textBox1.Text) <= 512 && Convert.ToInt16(textBox2.Text) >= 0 && Convert.ToInt16(textBox2.Text) <= 255) { sendBuf[17 + Convert.ToInt16(textBox1.Text)] = Convert.ToByte(textBox2.Text); } else MessageBox.Show("通道或数值参数输入有误"); '''
client端
# udp_gb_client.py '''客户端(UDP协议局域网广播)''' import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) PORT = 6454 s.bind(('127.0.0.1', PORT)) print('Listening for broadcast at ', s.getsockname()) while True: data, address = s.recvfrom(65535) print('Server received from {}:{}'.format(address, data))
python之UDP编程
UDP --- 用户数据报协议(User Datagram Protocol),是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
测试方法:使用terminal终端测试,使用 nc -u ip 端口 测试客户端;使用 nc -lu ip 端口 测试服务器端
1.接收一次数据
import socket # 设置服务器默认端口号 PORT = 9002 # 创建一个套接字socket对象,用于进行通讯 # socket.AF_INET 指明使用INET地址集,进行网间通讯 # socket.SOCK_DGRAM 指明使用数据协议,即使用传输层的udp协议 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) address = ("", PORT) # 为服务器绑定一个固定的地址,ip和端口 server_socket.bind(address) # 接收客户端传来的数据 recvfrom接收客户端的数据,默认是阻塞的,直到有客户端传来数据 # recvfrom 参数的意义,表示最大能接收多少数据,单位是字节 # recvfrom返回值说明 # receive_data表示接受到的传来的数据,是bytes类型, receive_data.decode()解码,将bytes类型转换为字符串类型 # client_address 表示传来数据的客户端的身份信息,客户端的ip和端口,元组 receive_data, client = server_socket.recvfrom(1024) print("来自客户端%s,发送的%s" % (client, receive_data.decode())) # 不再接收数据的时候,将套接字socket关闭 server_socket.close()
测试
2.循环多次接收数据
import socket PORT = 9002 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) address = ("192.168.219.129", PORT) server_socket.bind(address) while True: receive_data, client_address = server_socket.recvfrom(1024) print("接收到了客户端 %s 传来的数据: %s" % (client_address, receive_data.decode()))
3.发送一次数据
import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) msg = input("请输入要发送的内容:") # 字符串类型, 通过msg.encode() 编码 转换为bytes类型 server_address = ("127.0.0.1", 8000) # 接收方 服务器的ip地址和端口号 client_socket.sendto(msg.encode(), server_address) client_socket.close()
4.循环多次发送数据
import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: msg = input("请输入要发送的内容:") server_address = ("192.168.79.127", 8000) client_socket.sendto(msg.encode(), server_address)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。