简体   繁体   English

为什么使用 struct 打包生存时间(ttl)?

[英]Why is the time-to-live(ttl) packed using struct?

I stumbled upon some code in the book PyMOTW3 ( https://pymotw.com/3/socket/multicast.html ) and I could not understand why the time to live(ttl) argument was packed as struct.pack('b',1) .我在 PyMOTW3( https://pymotw.com/3/socket/multicast.html )一书中偶然发现了一些代码,我不明白为什么将生存时间(ttl)参数打包为struct.pack('b' ,1)

I tried searching the manuals to see if the arguments are supposed to be packed but it states that it can be integers.我尝试搜索手册以查看参数是否应该打包,但它指出它可以是整数。 I tried inputting a normal integer and it seemed to work fine.我尝试输入一个普通整数,它似乎工作正常。 It gave the same output as the code below.它给出了与下面代码相同的输出。 Then is there a specific reason why it has been packed like this ?那么它被包装成这样有什么具体的原因吗? I do know that packing it as 1 is unnecessary because the default value is 1 , but what if I need to use some other number.我知道将它打包为1是不必要的,因为默认值为 1 ,但是如果我需要使用其他数字怎么办。 Do I need to pack it?我需要打包吗?

I have included the code from the book below.我已经包含了下面书中的代码。

import socket
import struct
import sys

message = b'very important data'
multicast_group = ('224.3.29.71', 10000)

# Create the datagram socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Set a timeout so the socket does not block
# indefinitely when trying to receive data.
sock.settimeout(0.2)

# Set the time-to-live for messages to 1 so they do not
# go past the local network segment.
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
print(s.getsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL))

try:

    # Send data to the multicast group
    print('sending {!r}'.format(message))
    sent = sock.sendto(message, multicast_group)

    # Look for responses from all recipients
    while True:
        print('waiting to receive')
        try:
            data, server = sock.recvfrom(16)
        except socket.timeout:
            print('timed out, no more responses')
            break
        else:
            print('received {!r} from {}'.format(
                data, server))

finally:
    print('closing socket')
    sock.close()

This is the output I get whether I pack it or use a normal integer.无论是打包还是使用普通整数,这都是我得到的输出。

1 1

Sending very important message发送非常重要的信息

Timed Out!时间到!

Closing Socket关闭套接字

All packets consist of bytes.所有数据包都由字节组成。

For the AF_INET or an IPv4 you can see the distribution of bits among the properties of the packet in this picture .对于 AF_INET 或IPv4,您可以在这张图片中看到数据包属性之间的位分布。 You can see in the IPv4 header, TTL is the 9th octet of 20. TTL is an 8-bit (1-byte) field and can be from 0 to 255.您可以在 IPv4 标头中看到, TTL是 20 的第 9 个八位字节。TTL 是一个 8 位(1 字节)字段,可以是 0 到 255。

That is, each property should take a certain number of bits.也就是说,每个属性都应该占用一定数量的位。

For this purpose, Python 3.7 has a module struct .为此,Python 3.7 有一个模块struct This module performs conversions between Python values and C structs represented as Python bytes objects.该模块执行 Python 值和表示为 Python 字节对象的 C 结构之间的转换。

Since TTL is a positive integer of 1 byte in size, we have to select the unsigned char type, which is 'B'.由于 TTL 是大小为 1 个字节的正整数,因此我们必须选择 unsigned char 类型,即 'B'。

And so now the code looks like this:所以现在代码看起来像这样:

ttl = struct.pack('B', 25)  # unsigned char as 1-byte object
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM