为UDP客户端程序创建全局变量

发布于 2025-01-23 19:39:54 字数 2892 浏览 2 评论 0 原文

我正在创建一个UDP隧道客户端程序,以从客户端OS系统接收随机数据包,并使用读取器线程函数将数据包发送到UDP服务器。同样,我正在从UDP服务器读取数据包并将其发送到客户端的隧道IP地址。读者和作者线程必须同时运行。执行程序时,我会遇到以下错误。

use of moved value: `socket`
value used here after moverustcE0382
basic.rs(68, 38): value moved into closure here
basic.rs(74, 21): variable moved due to use in closure
basic.rs(101, 21): use occurs due to use in closure
basic.rs(58, 9): move occurs because `socket` has type `UdpSocket`, which does not implement the `Copy` trait

当我使用关键字移动时,如何将套接字变量声明为全局变量以删除作者线程中发生的错误?

let socket = UdpSocket::bind("8.0.0.1:8000") //create client socket object with ip and port
                       .expect("Could not bind client socket");

socket.connect("8.0.0.10:8888") //SERVER IP /PORT
                      .expect("Could not connect to server");

thread::sleep(time::Duration::from_secs(5)); // PROVIDING TIME TO ESTABLISH SOCKET CONNECTION TO SERVER



let reader_session = session.clone();

let reader = std::thread::spawn( move || {
    while RUNNING.load(Ordering::Relaxed) {
        match reader_session.receive_blocking() {
            Ok(packet) => {                     //receiving random packets from OS
                let bytes = packet.bytes();
                let leng = bytes.len();
                socket.send(&bytes[0..leng]);     //SENDING RANDOM PACKETS TO SERVER

                println!
                (
                    "Version & IHL: {}  Service Type: {}  Packet Length: {} {}  Identification: {} {}  Flags&Fragment: {} {}  
                    TTL: {}  Protocol: {}  Checksum: {} {}  SourceIP: {}.{}.{}.{}  DestIP: {}.{}.{}.{}",
                    &bytes[0],&bytes[1],&bytes[2],&bytes[3],&bytes[4],&bytes[5],&bytes[6],&bytes[7],
                    &bytes[8],&bytes[9],&bytes[10],&bytes[11],
                    &bytes[12],&bytes[13],&bytes[14],&bytes[15],&bytes[16],&bytes[17],&bytes[18],&bytes[19]
                );
                println!();
                
            }
            
            Err(_) => println!("Got error while reading packet"),
        }
    }
});


 
let writer_session = session.clone();
let writer_socket = socket.try_clone()?;
let writer = std::thread::spawn(move || {
    info!("Starting writer");

while RUNNING.load(Ordering::Relaxed) {
        let mut buffer = [0u8; 1500]; 
                writer_socket.recv_from(&mut buffer) //get message from server
                     .expect("Could not read into buffer");
        let mut leng1 = buffer.len();


                println!("From server: {}", str::from_utf8(&buffer) //print message from server
                     .expect("Could not write buffer as string"));
                     socket.send_to(&buffer[0..leng1],"6.0.0.1"); //send message from server to tunnel ip
    }
});

I am creating a UDP tunnel client program to receive random packets from client OS system and send the data packets to a UDP server using a reader thread function. Similarly I am reading packets from the UDP server and sending it to the client's tunnel IP address. The reader and writer threads must run simultaneously. I get the following error when I execute the program.

use of moved value: `socket`
value used here after moverustcE0382
basic.rs(68, 38): value moved into closure here
basic.rs(74, 21): variable moved due to use in closure
basic.rs(101, 21): use occurs due to use in closure
basic.rs(58, 9): move occurs because `socket` has type `UdpSocket`, which does not implement the `Copy` trait

How do I declare the socket variable as global variable to remove the error occurring at writer thread when I use the keyword move?

let socket = UdpSocket::bind("8.0.0.1:8000") //create client socket object with ip and port
                       .expect("Could not bind client socket");

socket.connect("8.0.0.10:8888") //SERVER IP /PORT
                      .expect("Could not connect to server");

thread::sleep(time::Duration::from_secs(5)); // PROVIDING TIME TO ESTABLISH SOCKET CONNECTION TO SERVER



let reader_session = session.clone();

let reader = std::thread::spawn( move || {
    while RUNNING.load(Ordering::Relaxed) {
        match reader_session.receive_blocking() {
            Ok(packet) => {                     //receiving random packets from OS
                let bytes = packet.bytes();
                let leng = bytes.len();
                socket.send(&bytes[0..leng]);     //SENDING RANDOM PACKETS TO SERVER

                println!
                (
                    "Version & IHL: {}  Service Type: {}  Packet Length: {} {}  Identification: {} {}  Flags&Fragment: {} {}  
                    TTL: {}  Protocol: {}  Checksum: {} {}  SourceIP: {}.{}.{}.{}  DestIP: {}.{}.{}.{}",
                    &bytes[0],&bytes[1],&bytes[2],&bytes[3],&bytes[4],&bytes[5],&bytes[6],&bytes[7],
                    &bytes[8],&bytes[9],&bytes[10],&bytes[11],
                    &bytes[12],&bytes[13],&bytes[14],&bytes[15],&bytes[16],&bytes[17],&bytes[18],&bytes[19]
                );
                println!();
                
            }
            
            Err(_) => println!("Got error while reading packet"),
        }
    }
});


 
let writer_session = session.clone();
let writer_socket = socket.try_clone()?;
let writer = std::thread::spawn(move || {
    info!("Starting writer");

while RUNNING.load(Ordering::Relaxed) {
        let mut buffer = [0u8; 1500]; 
                writer_socket.recv_from(&mut buffer) //get message from server
                     .expect("Could not read into buffer");
        let mut leng1 = buffer.len();


                println!("From server: {}", str::from_utf8(&buffer) //print message from server
                     .expect("Could not write buffer as string"));
                     socket.send_to(&buffer[0..leng1],"6.0.0.1"); //send message from server to tunnel ip
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞觅青森が 2025-01-30 19:39:54

您应该能够使用 udpsocket 使用 try_clone()方法,该方法创建一个新变量,引用相同的基础套接字。

例如

...
let reader_session = session.clone();
let reader_socket = socket.try_clone().expect("Couldn't clone the socket");

let reader = std::thread::spawn( move || {
...
       reader_socket.send(&bytes[0..leng]);

You should be able to clone the UdpSocket using the try_clone() method which creates a new variable referencing the same underlying socket.

e.g.

...
let reader_session = session.clone();
let reader_socket = socket.try_clone().expect("Couldn't clone the socket");

let reader = std::thread::spawn( move || {
...
       reader_socket.send(&bytes[0..leng]);

https://doc.rust-lang.org/std/net/struct.UdpSocket.html#method.try_clone

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文