Структура 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.