[−][src]Enum nix::sys::socket::ControlMessage
A type-safe wrapper around a single control message. More types may be added to this enum; do not exhaustively pattern-match it. Further reading
Variants
ScmRights(&'a [RawFd])
A message of type SCM_RIGHTS
, containing an array of file
descriptors passed between processes.
See the description in the "Ancillary messages" section of the unix(7) man page.
ScmTimestamp(&'a TimeVal)
A message of type SCM_TIMESTAMP
, containing the time the
packet was received by the kernel.
See the kernel's explanation in "SO_TIMESTAMP" of networking/timestamping.
Examples
use nix::sys::socket::*; use nix::sys::uio::IoVec; use nix::sys::time::*; use std::time::*; // Set up let message1 = "Ohayō!".as_bytes(); let message2 = "Jā ne".as_bytes(); let in_socket = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap(); setsockopt(in_socket, sockopt::ReceiveTimestamp, &true).unwrap(); bind(in_socket, &SockAddr::new_inet(InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0))).unwrap(); let address = if let Ok(address) = getsockname(in_socket) { address } else { unreachable!() }; // Send both assert!(Ok(message1.len()) == sendmsg(in_socket, &[IoVec::from_slice(message1)], &[], MsgFlags::empty(), Some(&address))); let time = SystemTime::now(); std::thread::sleep(Duration::from_millis(250)); assert!(Ok(message2.len()) == sendmsg(in_socket, &[IoVec::from_slice(message2)], &[], MsgFlags::empty(), Some(&address))); let delay = time.elapsed().unwrap(); // Receive the first let mut buffer1 = vec![0u8; message1.len() + message2.len()]; let mut time1: CmsgSpace<TimeVal> = CmsgSpace::new(); let received1 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer1)], Some(&mut time1), MsgFlags::empty()).unwrap(); let mut time1 = if let Some(ControlMessage::ScmTimestamp(&time1)) = received1.cmsgs().next() { time1 } else { panic!("Unexpected or no control message") }; // Receive the second let mut buffer2 = vec![0u8; message1.len() + message2.len()]; let mut time2: CmsgSpace<TimeVal> = CmsgSpace::new(); let received2 = recvmsg(in_socket, &[IoVec::from_mut_slice(&mut buffer2)], Some(&mut time2), MsgFlags::empty()).unwrap(); let mut time2 = if let Some(ControlMessage::ScmTimestamp(&time2)) = received2.cmsgs().next() { time2 } else { panic!("Unexpected or no control message") }; // Swap if needed; UDP is unordered match (received1.bytes, received2.bytes, message1.len(), message2.len()) { (l1, l2, m1, m2) if l1 == m1 && l2 == m2 => {}, (l2, l1, m1, m2) if l1 == m1 && l2 == m2 => { std::mem::swap(&mut time1, &mut time2); std::mem::swap(&mut buffer1, &mut buffer2); }, _ => panic!("Wrong packets"), }; // Compare results println!("{:?} @ {:?}, {:?} @ {:?}, {:?}", buffer1, time1, buffer2, time2, delay); assert!(message1 == &buffer1[0..(message1.len())], "{:?} == {:?}", message1, buffer1); assert!(message2 == &buffer2[0..(message2.len())], "{:?} == {:?}", message2, buffer2); let time = time2 - time1; let time = Duration::new(time.num_seconds() as u64, time.num_nanoseconds() as u32); let difference = if delay < time { time - delay } else { delay - time }; assert!(difference.subsec_nanos() < 5_000_000, "{}ns < 5ms", difference.subsec_nanos()); assert!(difference.as_secs() == 0); // Close socket nix::unistd::close(in_socket).unwrap();
Auto Trait Implementations
impl<'a> Send for ControlMessage<'a>
impl<'a> Sync for ControlMessage<'a>
Blanket Implementations
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,