Структура SocketAddrV4
#![allow(unused)] fn main() { pub struct SocketAddrV4 { /* приватные поля */ } }
Адрес интернет-сокса IPv4.
SocketAddrV4 включает в себя адрес IPv4 и номер порта.
См. также SocketAddr для типа, представляющий либо IPv4, либо IPv6 адрес сокета.
Представление в памяти
SocketAddrV4 имеет то же представление в памяти, что и соответствующая структура C sockaddr_in.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); assert_eq!( "127.0.0.1:8080".parse(), Ok(socket) ); }
Методы
new
#![allow(unused)] fn main() { pub const fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 }
Создает новый адрес сокета IPv4 из Ipv4Addr и номера порта.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let addr = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); assert_eq!(addr.ip(), &Ipv4Addr::new(127, 0, 0, 1)); assert_eq!(addr.port(), 8080); }
ip
#![allow(unused)] fn main() { pub const fn ip(&self) -> &Ipv4Addr }
Возвращает IP-адрес, связанный с этим адресом сокета.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1)); }
port
#![allow(unused)] fn main() { pub const fn port(&self) -> u16 }
Возвращает номер порта, связанный с этим адресом сокета.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); assert_eq!(socket.port(), 8080); }
set_ip
#![allow(unused)] fn main() { pub fn set_ip(&mut self, new_ip: Ipv4Addr) }
Устанавливает IP-адрес, связанный с этим адресом сокета.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); socket.set_ip(Ipv4Addr::new(192, 168, 1, 1)); assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 1, 1)); }
set_port
#![allow(unused)] fn main() { pub fn set_port(&mut self, new_port: u16) }
Устанавливает номер порта, связанный с этим адресом сокета.
Примеры
#![allow(unused)] fn main() { use std::net::{Ipv4Addr, SocketAddrV4}; let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); socket.set_port(9090); assert_eq!(socket.port(), 9090); }
Трайт-реализации
From<SocketAddrV4>
#![allow(unused)] fn main() { impl From<SocketAddrV4> for SocketAddr }
Преобразует SocketAddrV4 в SocketAddr.
Примеры
#![allow(unused)] fn main() { use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; let socket_v4 = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080); let socket_addr = SocketAddr::from(socket_v4); assert_eq!(socket_addr.ip().to_string(), "127.0.0.1"); assert_eq!(socket_addr.port(), 8080); }
Display, Debug
#![allow(unused)] fn main() { impl Display for SocketAddrV4 impl Debug for SocketAddrV4 }
Реализует отображение и отладочное отображение для SocketAddrV4.
Примеры
#![allow(unused)] fn main() { use std::net::{SocketAddrV4, Ipv4Addr}; let socket = SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 8080); println!("Адрес сокета: {}", socket); // "192.168.1.1:8080" println!("Отладочная информация: {:?}", socket); // "192.168.1.1:8080" }
PartialEq, Eq, PartialOrd, Ord, Hash
#![allow(unused)] fn main() { impl PartialEq for SocketAddrV4 impl Eq for SocketAddrV4 impl PartialOrd for SocketAddrV4 impl Ord for SocketAddrV4 impl Hash for SocketAddrV4 }
Реализует сравнение и хеширование для SocketAddrV4.
Примеры
#![allow(unused)] fn main() { use std::net::{SocketAddrV4, Ipv4Addr}; use std::collections::HashMap; let socket1 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 8080); let socket2 = SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 8080); let socket3 = SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 8080); assert_eq!(socket1, socket2); assert_ne!(socket1, socket3); let mut map = HashMap::new(); map.insert(socket1, "server1"); }
FromStr
#![allow(unused)] fn main() { impl FromStr for SocketAddrV4 }
Реализует парсинг из строки для SocketAddrV4.
Примеры
#![allow(unused)] fn main() { use std::net::SocketAddrV4; use std::str::FromStr; let socket = SocketAddrV4::from_str("127.0.0.1:8080").unwrap(); assert_eq!(socket.port(), 8080); }
Примеры использования
Создание и манипуляция адресами сокетов IPv4
use std::net::{SocketAddrV4, Ipv4Addr}; fn demonstrate_socketaddr_v4() { // Создание базового адреса сокета let mut socket = SocketAddrV4::new( Ipv4Addr::new(192, 168, 1, 1), 8080, ); println!("Исходный адрес: {}", socket); println!(" IP: {}", socket.ip()); println!(" Порт: {}", socket.port()); // Изменение полей socket.set_ip(Ipv4Addr::new(10, 0, 0, 1)); socket.set_port(9090); println!("\nПосле изменений:"); println!(" Адрес: {}", socket); println!(" IP: {}", socket.ip()); println!(" Порт: {}", socket.port()); } fn main() { demonstrate_socketaddr_v4(); }
Использование в сетевых операциях
use std::net::{TcpListener, UdpSocket, SocketAddrV4, Ipv4Addr}; use std::io; fn create_ipv4_server() -> io::Result<()> { // Создание TCP слушателя на IPv4 let socket_addr = SocketAddrV4::new( Ipv4Addr::new(0, 0, 0, 0), // 0.0.0.0 (все интерфейсы) 8080, ); let tcp_listener = TcpListener::bind(socket_addr)?; println!("TCP сервер слушает на: {}", tcp_listener.local_addr()?); // Создание UDP сокета на IPv4 let udp_socket = UdpSocket::bind(socket_addr)?; println!("UDP сокет привязан к: {}", udp_socket.local_addr()?); Ok(()) } fn connect_to_ipv4_server() -> io::Result<()> { let server_addr = SocketAddrV4::new( Ipv4Addr::new(127, 0, 0, 1), 8080, ); // Попытка подключения по TCP match std::net::TcpStream::connect(server_addr) { Ok(_stream) => println!("Успешное подключение к серверу"), Err(e) => println!("Ошибка подключения: {}", e), } Ok(()) } fn main() -> io::Result<()> { create_ipv4_server()?; connect_to_ipv4_server()?; Ok(()) }
Преобразование между различными форматами
use std::net::{SocketAddr, SocketAddrV4, Ipv4Addr}; fn demonstrate_conversions() { // Создание SocketAddrV4 let socket_v4 = SocketAddrV4::new( Ipv4Addr::new(192, 168, 1, 1), 8080, ); println!("SocketAddrV4: {}", socket_v4); println!(" IP: {}", socket_v4.ip()); println!(" Порт: {}", socket_v4.port()); // Преобразование в SocketAddr let socket_addr = SocketAddr::from(socket_v4); println!("\nПосле преобразования в SocketAddr:"); println!(" SocketAddr: {}", socket_addr); println!(" IP: {}", socket_addr.ip()); println!(" Порт: {}", socket_addr.port()); println!(" is_ipv4(): {}", socket_addr.is_ipv4()); println!(" is_ipv6(): {}", socket_addr.is_ipv6()); // Обратное преобразование (если это IPv4) if let SocketAddr::V4(socket_v4_again) = socket_addr { println!("\nОбратное преобразование:"); println!(" SocketAddrV4: {}", socket_v4_again); } } fn main() { demonstrate_conversions(); }
Парсинг из строки
use std::net::SocketAddrV4; use std::str::FromStr; fn demonstrate_parsing() { let test_cases = [ "127.0.0.1:8080", "192.168.1.1:80", "0.0.0.0:0", "255.255.255.255:65535", "10.0.0.1:443", ]; println!("Парсинг IPv4 адресов сокетов:"); for test_case in &test_cases { match SocketAddrV4::from_str(test_case) { Ok(socket) => { println!(" ✓ '{}' -> {}", test_case, socket); println!(" IP: {}", socket.ip()); println!(" Порт: {}", socket.port()); } Err(e) => { println!(" ✗ '{}' -> Ошибка: {}", test_case, e); } } println!(); } } fn main() { demonstrate_parsing(); }
Работа с различными типами адресов
use std::net::{SocketAddrV4, Ipv4Addr}; fn demonstrate_address_types() { let special_addresses = [ SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 8080), // 0.0.0.0 SocketAddrV4::new(Ipv4Addr::LOCALHOST, 8080), // 127.0.0.1 SocketAddrV4::new(Ipv4Addr::BROADCAST, 8080), // 255.255.255.255 SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 8080), // Частный SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 8080), // Частный SocketAddrV4::new(Ipv4Addr::new(172, 16, 0, 1), 8080), // Частный SocketAddrV4::new(Ipv4Addr::new(169, 254, 0, 1), 8080), // Link-local SocketAddrV4::new(Ipv4Addr::new(224, 0, 0, 1), 8080), // Multicast ]; println!("Специальные IPv4 адреса сокетов:"); for socket in &special_addresses { let ip = socket.ip(); println!(" Адрес: {}", socket); println!(" Неспецифицированный: {}", ip.is_unspecified()); println!(" Обратная петля: {}", ip.is_loopback()); println!(" Частный: {}", ip.is_private()); println!(" Link-local: {}", ip.is_link_local()); println!(" Многоадресный: {}", ip.is_multicast()); println!(" Широковещательный: {}", ip.is_broadcast()); println!(); } } fn main() { demonstrate_address_types(); }
Использование в коллекциях
use std::net::{SocketAddrV4, Ipv4Addr}; use std::collections::{HashMap, HashSet}; fn demonstrate_collections() { // Создание нескольких адресов сокетов let addresses = vec![ SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 80), SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 443), SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 2), 80), SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 8080), ]; // Использование в HashSet (уникальные адреса) let unique_addresses: HashSet<_> = addresses.iter().collect(); println!("Уникальные адреса в HashSet:"); for addr in &unique_addresses { println!(" {}", addr); } // Использование в HashMap let mut server_map = HashMap::new(); server_map.insert( SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 80), "Веб-сервер", ); server_map.insert( SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 443), "HTTPS-сервер", ); server_map.insert( SocketAddrV4::new(Ipv4Addr::new(10, 0, 0, 1), 8080), "Внутренний сервер", ); println!("\nСерверы в HashMap:"); for (addr, description) in &server_map { println!(" {} -> {}", addr, description); } // Поиск в коллекциях let search_addr = SocketAddrV4::new(Ipv4Addr::new(192, 168, 1, 1), 80); if let Some(description) = server_map.get(&search_addr) { println!("\nНайден сервер: {} -> {}", search_addr, description); } } fn main() { demonstrate_collections(); }
Особенности IPv4 сокетов
Представление в памяти
Совместимо с системной структурой sockaddr_in, что позволяет напрямую использовать в системных вызовах.
Сравнение и хеширование
Два SocketAddrV4 считаются равными, если у них одинаковый IP-адрес и порт. Это позволяет использовать их как ключи в HashMap и HashSet.
Преобразования
Легко преобразуется в и из SocketAddr, что обеспечивает гибкость при работе с кодом, который должен поддерживать как IPv4, так и IPv6.