python udp发送注意事项:
1、udp客户端不需绑定端口号
2、udp发送报文时,需考虑大、小字段,格式对齐等
3、udp 发送报文格式对齐,使用到struct.pack(format,data),解包时使用struct.unpack(format,data)
struct支持的数据类型为:
format | ctype | python | 字节数 |
x | pad byte | no value | 1 |
c | char | string of length 1 | 1 |
b | signed char | integer | 1 |
B | unsigned char | integer | 1 |
? | _Bool | bool | 1 |
h | short | integer | 2 |
H | unsigned short | integer | 2 |
i | int | integer | 4 |
I | unsinged int | integer or long | 4 |
l | long | integer | 4 |
L | unsigned long | long | 4 |
q | long long | long | 8 |
Q | unsigned long long | long | 8 |
f | float | float | 4 |
d | double | float | 8 |
s | char[] | string | 1 |
p | char[] | string | 1 |
P | void* | long |
如下代码为第一种发送方式,通过struct.pack发送:
import struct
import threading
import pandas as pd
import numpy as np
import socket
import time
#继承thread
class threadStateSend(threading.Thread):
def __init__(self,threadID,threadName):
threading.Thread.__init__(self)
self.threadID = threadID
self.threadName = threadName
state1 = 10
state2 = 20
state3 = 30
state4 = 40
stateFormat = '>hl'+ ("h"*2) #格式为大端,由高位到地位放置,类型分别为:short(2)、long(4)、short(2)、short(2)
def run(self):
SERVER_PORT = 8000 # 服务端端口号
CLIENT_PORT = 8300 #客户端绑定的端口号
client_sorcket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建socket
client_address = ("127.0.0.1", CLIENT_PORT) #客户端绑定ip地址
client_sorcket.bind(client_address) # 客户端绑定的ip及端口,若不绑定,则随机取端口
server_address = ("127.0.0.1", SERVER_PORT) #服务端ip地址
sendStateData = struct.pack(self.stateFormat,
self.state1,
self.state2,
self.state3,
self.state4)
client_sorcket.sendto(sendStateData,server_address)
第二种发送udp方式:通过逐行读取csv的数据,并将每行数据组织为bytes发送。
代码如下:
'''
通过读取csv(csv:第一行为字段占字节数,其余行为发送的数据)发送数据信息
读取csv数据,周期性的发送每一行数据
'''
import threading
import pandas as pd
import numpy as np
import socket
import time
class threadSrDataSend(threading.Thread):
def __init__(self,threadID,threadName):
threading.Thread.__init__(self)
self.threadID = threadID
self.threadName = threadName
def run(self):
SERVER_PORT = 8000 # 服务端端口号
CLIENT_PORT = 8200 #客户端绑定的端口号
client_sorcket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建socket
server_address = ("127.0.0.1", SERVER_PORT) #服务端ip地址
client_address = ("127.0.0.1", CLIENT_PORT) #客户端绑定ip地址
client_sorcket.bind(client_address) # 客户端绑定的ip及端口,若不绑定,则随机取端口
data = pd.read_csv("data.csv", header=None) #dataFrame
data = np.array(data) #dataFrame转换为ndArray
dataByte = data[0] #获取每个字段对应的字节数
dataSends = np.delete(data, 0, axis = 0) #获取要发送的数据
sendData2Target = b'' #发送的数据
for sendData in dataSends:
for sendDataValue, sendDataByte in zip(sendData,dataByte):
sendDataValue = int(sendDataValue) #将int64类型转换为int类型
#将此字段转换为固定字节数,按小端存放
sendData2Target = sendData2Target + sendDataValue.to_bytes(sendDataByte,"big")
client_sorcket.sendto(sendData2Target, server_address) #发送数据
sendData2Target = b'' #将发送的数据置空
time.sleep(2) #间隔2s
sockt接收
import socket
import struct
PORT = 8000
receiveSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建socket
address = ("127.0.0.1", PORT)
receiveSocket.bind(address) #绑定ip及端口
rcvDatas = []
while(True):
print("等待接收msg")
message, client = receiveSocket.recvfrom(1024) #接收数据
data = struct.unpack('>hL',message) #接收的数据 ">:表示大端,h:unsign short 2个字节,L:unsign long 4个字节"
print(data[0],data[1])
rcvDatas.append(list(data))
print(rcvDatas)