class SF::Packet
inherits Reference
#
Utility class to build blocks of data to transfer over the network
Packets provide a safe and easy way to serialize data,
in order to send it over the network using sockets
(SF::TcpSocket
, SF::UdpSocket
).
Packets solve 2 fundamental problems that arise when transferring data over the network:
- data is interpreted correctly according to the endianness
- the bounds of the packet are preserved (one send == one receive)
The SF::Packet
class provides both input and output, using read
and write
methods.
It is recommended to use only fixed-size types (like Int32
, etc.),
to avoid possible differences between the sender and the receiver.
Usage example:
x = 24u32
s = "hello"
d = 5.89
# Group the variables to send into a packet
packet = SF::Packet.new
packet.write x
packet.write s
packet.write d
# Send it over the network (socket is a valid SF::TcpSocket)
socket.send packet
# -----------------------------------------------------------------
# Receive the packet at the other end
packet = SF::Packet.new
socket.receive(packet)
# Extract the variables contained in the packet
x = packet.read UInt32
s = packet.read String
d = packet.read Float64
if packet.valid?
# Data extracted successfully...
end
Packets have overloads of read
and write
methods for standard types:
- Bool
- Fixed-size integer types (
Int8/16/32/64
,UInt8/16/32/64
) - Floating point numbers (
Float32/64
) String
Like standard streams, it is also possible to define your own overloads of these methods in order to handle your custom types.
struct MyStruct
number : Float32
integer : Int8
str : String
end
class SF::Packet
def write(m : MyStruct)
write m.number
write m.integer
write m.str
end
def read(type : MyStruct.class) : MyStruct
MyStruct.new(packet.read(Float32), packet.read(Int8), packet.read(String))
end
end
See also: SF::TcpSocket
, SF::UdpSocket
Constructors#
Methods#
#append(data : Slice)
#
Append data to the end of the packet
- data - Pointer to the sequence of bytes to append
- size_in_bytes - Number of bytes to append
See also: clear
See also: read_position
#data : ::Pointer(Void)
#
Get a pointer to the data contained in the packet
Warning
The returned pointer may become invalid after you append data to the packet, therefore it should never be stored. The return pointer is NULL if the packet is empty.
Returns: Pointer to the data
See also: data_size
#data_size : Int32
#
Get the size of the data contained in the packet
This function returns the number of bytes pointed to by what data returns.
Returns: Data size, in bytes
See also: data
#dup : Packet
#
Returns a shallow copy of this object.
This allocates a new object and copies the contents of
self
into it.
#end_of_packet : Bool
#
Tell if the reading position has reached the end of the packet
This function is useful to know if there is some data left to be read, without actually reading it.
Returns: True if all data was read, false otherwise
See also: operator
bool
#read(type : Bool.class) : Bool
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Int8.class) : Int8
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : UInt8.class) : UInt8
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Int16.class) : Int16
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : UInt16.class) : UInt16
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Int32.class) : Int32
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : UInt32.class) : UInt32
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Int64.class) : Int64
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : UInt64.class) : UInt64
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Float32.class) : Float32
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : Float64.class) : Float64
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read(type : String.class) : String
#
Read data from the packet. The expected type corresponds to what was actually sent.
#read_position : Int32
#
Get the current reading position in the packet
The next read operation will read data from this position
Returns: The byte offset of the current read position
See also: append
#valid? : Bool
#
Test the validity of the packet, for reading
This operator allows to test the packet as a boolean variable, to check if a reading operation was successful.
A packet will be in an invalid state if it has no more data to read.
This behavior is the same as standard C++ streams.
Usage example:
x = packet.read(Float32)
if packet.valid?
# ok, x was extracted successfully
end
Returns: True if last data extraction from packet was successful
See also: end_of_packet