rust ipv6 udp reverse echo server and client

server
监听在 udp4 和 6 的端口, buf大小为2048, 超过的会丢弃。
将接受到的 内容 反转后 发回给客户端

use std::net::UdpSocket;


fn main() -> std::io::Result<()> {
    //let socket = UdpSocket::bind("0.0.0.0:2000")?; // for UDP4
    let socket = UdpSocket::bind("[::]:2000")?;  // for UDP4/6
    let mut buf = [0; 2048];

    loop {
        // Receives a single datagram message on the socket.
        // If `buf` is too small to hold
        // the message, it will be cut off.
        let (amt, src) = socket.recv_from(&mut buf)?;

        // Redeclare `buf` as slice of the received data
	// and send data back to origin.
        let buf = &mut buf[..amt];

        //reverse
        buf.reverse();

        socket.send_to(buf, &src)?;
    }
}

client

use std::io::{self, BufRead};
use std::net::UdpSocket;
use std::env;
use std::str;

fn main() -> std::io::Result<()> {

    let args: Vec = env::args().collect();
    if args.len() < 2 {
        println!("Usage {} hostname", args[0]);
        std::process::exit(1);
    }
    let hostname = &args[1];

    let socket = UdpSocket::bind("[::]:0")?;  // for UDP4/6
    
    socket.connect(hostname.to_string() + &":2000").expect("couldn't connect to address");

    // from https://stackoverflow.com/questions/30186037/how-can-i-read-a-single-line-from-stdin
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        println!("Line read from stdin '{}'", line);
        if &line == "BYE" {
            break;
        }

        //socket.send_to(line.as_bytes(), hostname.to_string() + &":2000").expect("Error on send");
        socket.send(line.as_bytes()).expect("Error on send");

        let mut buf = [0; 2048];
        let (amt, _src) = socket.recv_from(&mut buf)?;

        let echo = str::from_utf8(&buf[..amt]).unwrap();
        println!("Echo {}", echo);
    }
    
    Ok(())
}

udp的connect 是可以直接接受 “hostname:port” 字符串形式的参数的, 它会自动进行DNS解析

可以互通的python client

import socket 
import sys 
import argparse 
 
data_payload = 2048 
 
def echo_client(server, port): 
    """ A simple echo client """ 
    # Create a UDP socket 
    sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) 
 
    server_address = (server, port) 
    print ("Connecting to %s port %s" % server_address) 
    message = 'This is the message.  It will be repeated.' 
 
    try: 
 
        # Send data 
        message = "Test message. This will be echoed" 
        print ("Sending= %s" % message) 
        sent = sock.sendto(message.encode('utf-8'), server_address) 
 
        # Receive response 
        data, server = sock.recvfrom(data_payload) 
        print ("received= %s" % data) 
 
    finally: 
        print ("Closing connection to the server") 
        sock.close() 
 
if __name__ == '__main__': 
    parser = argparse.ArgumentParser(description='Socket Server Example') 
    parser.add_argument('--port', action="store", dest="port", type=int, required=True) 
    parser.add_argument('--server', action="store", dest="server", type=str, required=True)     
    given_args = parser.parse_args()  
    port = given_args.port
    server = given_args.server
    
    echo_client(server, port) 

服务端

import socket 
import sys 
import argparse 
 
host = '::' 
data_payload = 2048 

 
def echo_server(port): 
    """ A simple echo server """ 

    # Create a UDP socket 
    sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) 
 
    # Bind the socket to the port 
    server_address = (host, port) 
    print ("Starting up echo server on %s port %s" % server_address) 
 
    sock.bind(server_address) 
 
    while True: 
        print ("Waiting to receive message from client") 
        data, address = sock.recvfrom(data_payload) 
     
        print ("received %s bytes from %s" % (len(data), address)) 
        print ("Data: %s" %data) 
     
        if data: 
            data = data[::-1]  # reverse
            sent = sock.sendto(data, address) 
            print ("sent %s bytes back to %s" % (sent, address)) 
 
 
if __name__ == '__main__': 

    parser = argparse.ArgumentParser(description='Socket Server Example')
    parser.add_argument('--port', action="store", dest="port", type=int, required=True) 
    given_args = parser.parse_args()  
    port = given_args.port 

    echo_server(port) 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注