如何从pythonsocket.sendmsg

问题描述 投票:0回答:1

在读取here的同时,HERHE和HERHE我看到,在Linux系统上,您可以通过设置套接字选项从接收和发送的数据包中请求时间戳。我目前可以使用SO_TIMESTAMPNS

SO_TIMESTAMPING
来获得带有
recvmsg
的RX时间戳。使用
sendmsg
我不知道如何正确打包控制消息的辅助数据,而sendmsg甚至没有可以持有我需要的数据的返回。
这就是我如何获得RX时间戳。
import socket SO_TIMESTAMPING = 37 SOF_TIMESTAMPING = 127 server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_sock.setsockopt(socket.SOL_SOCKET, SO_TIMESTAMPING, SO_TIMESTAMPING, SOF_TIMESTAMPING) server_sock.bind((_svr_ip, _svr_port)) server_sock.listen(_num_clients) conn, client_addr = server_sock.accept() msg, ancdata, flags, address = conn.recvmsg(64, 1024) t_rx = ancdata[0][2] t_rx_s = int.from_bytes(t_rec[0:7], byteorder="little") t_rx_ns = int.from_bytes(t_rec[8:], byteorder="little")

节1.3.4
提及通过控制消息启用时间戳,而无需使用
socket.setsockopt

保留开销。我相信这意味着您在调用sendmsg而不是使用

socket.setsockopt
.
时将标志添加到控制消息中。
    
您已经看到,sendmsg()中没有字段可以返回时间戳。  无论如何,这都是不切实际的。  sendmsg()仅将数据包排队到内核插座缓冲区。  仅当数据包实际发送时,TX时间戳才会生成。  对于硬件时间戳,实际上是由NIC生成的,当数据包在电线上熄灭时。

INSTEAD,TX时间戳发生的事情是将时间戳添加到插座“错误队列”中。错误队列是异步的辅助数据的通道。 这可能是一个网络错误,但即使不是错误,也用于时间戳。
python sockets network-programming socket.io timestamp
1个回答
0
投票
recvmsg

设置

MSG_ERRQUEUE

。 此调用将

not

返回任何实际的套接字数据。 取而代之的是,它返回传输数据包的副本,以及包含时间戳的固有数据字段。 您可以在使用

SOF_TIMESTAMPING_OPT_TSONLY
时使用
setsockopt
选项来抑制包含传输数据包的副本。 如果我修改您的示例以使用TXTimestamps

import socket    

SO_TIMESTAMPING = 37
SOF_TIMESTAMPING = 127

server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_sock.setsockopt(socket.SOL_SOCKET, SO_TIMESTAMPING, SOF_TIMESTAMPING)

server_sock.bind((_svr_ip, _svr_port))
server_sock.listen(_num_clients)
conn, client_addr = server_sock.accept()

conn.send(b"hello, world")
msg, ancdata, flags, address = conn.recvmsg(64, 1024, socket.MSG_ERRQUEUE)

for layer, opt, data in ancdata:
    if layer == socket.SOL_SOCKET and opt == sol.SO_TIMESTAMPING:
        t_send = data
        t_tx_s = int.from_bytes(t_send[0:7], byteorder="little")
        t_tx_ns = int.from_bytes(t_send[8:], byteorder="little")
        print(f"packet sent time: {t_tx_s}.{t_tx_ns:09}")
可以通过使用辅助数据更改每个调用的时间戳选项。  它应该看起来像这样:

SOF_TIMESTAMPING_TX_SOFTWARE = 2 opt_bytes = SOF_TIMESTAMPING_TX_SOFTWARE.to_bytes(4, 'little') conn.sendmsg([b'hello, world], [(socket.SOL_SOCKET, SO_TIMESTAMPING, opt_bytes)]) msg, ancdata, flags, address = conn.recvmsg(64, 1024, socket.MSG_ERRQUEUE)

我知道,您需要通常使用setSockopt启用的时间戳,但是您可以省略sof_timestamping_tx_software lit,然后将其应用于show的辅助数据。
	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.