fix
This commit is contained in:
parent
fb18d7c356
commit
55006eb3b1
65
Cargo.lock
generated
65
Cargo.lock
generated
@ -28,6 +28,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.75"
|
version = "0.3.75"
|
||||||
@ -202,9 +208,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.173"
|
version = "0.2.174"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb"
|
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
@ -265,10 +281,12 @@ dependencies = [
|
|||||||
name = "modbus_agent"
|
name = "modbus_agent"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
"futures",
|
"futures",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-modbus",
|
"tokio-modbus",
|
||||||
"tokio-serial",
|
"tokio-serial",
|
||||||
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -303,6 +321,29 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -333,6 +374,15 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.25"
|
version = "0.1.25"
|
||||||
@ -363,6 +413,15 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
@ -426,7 +485,9 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
|
|||||||
@ -8,4 +8,5 @@ tokio = { version = "1.45.1", features = ["full"] }
|
|||||||
tokio-modbus = "0.16.1"
|
tokio-modbus = "0.16.1"
|
||||||
tokio-serial = "5.4.1"
|
tokio-serial = "5.4.1"
|
||||||
futures = "0.3.31"
|
futures = "0.3.31"
|
||||||
|
byteorder = "1.5.0"
|
||||||
tokio-util = "0.7.15"
|
tokio-util = "0.7.15"
|
||||||
32
src/codec.rs
Normal file
32
src/codec.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use std::io::{Cursor, Read};
|
||||||
|
use byteorder::{BigEndian, ReadBytesExt};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct SerialConfig {
|
||||||
|
pub port: Vec<u8>, // Port/binary(变长二进制数据)
|
||||||
|
pub baudrate: u32, // Baudrate:32
|
||||||
|
pub stopbits: u8, // Stopbits:8
|
||||||
|
pub parity: u8, // Parity:8
|
||||||
|
pub timeout: u32, // Timeout:32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn parse_serial_config(data: &[u8]) -> std::io::Result<SerialConfig> {
|
||||||
|
let mut cursor = Cursor::new(data);
|
||||||
|
|
||||||
|
let port_len = cursor.read_u8()?;
|
||||||
|
let mut port = vec![0u8; port_len as usize];
|
||||||
|
cursor.read_exact(&mut port)?;
|
||||||
|
|
||||||
|
let baudrate = cursor.read_u32::<BigEndian>()?;
|
||||||
|
let stopbits = cursor.read_u8()?;
|
||||||
|
let parity = cursor.read_u8()?;
|
||||||
|
let timeout = cursor.read_u32::<BigEndian>()?;
|
||||||
|
|
||||||
|
Ok(SerialConfig {
|
||||||
|
port,
|
||||||
|
baudrate,
|
||||||
|
stopbits,
|
||||||
|
parity,
|
||||||
|
timeout,
|
||||||
|
})
|
||||||
|
}
|
||||||
99
src/main.rs
99
src/main.rs
@ -1,43 +1,94 @@
|
|||||||
|
mod codec;
|
||||||
|
|
||||||
use tokio::net::{UnixListener, UnixStream};
|
use tokio::net::{UnixListener, UnixStream};
|
||||||
//use tokio_util::codec::{Framed, LinesCodec};
|
//use tokio_util::codec::{Framed, LinesCodec};
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
//use tokio::io::AsyncReadExt;
|
//use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
const SOCKET_PATH: &str = "/tmp/modbus.sock";
|
use std::io::{self, Read, Write};
|
||||||
|
use std::process;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() {
|
||||||
// 绑定Unix Domain Socket
|
let stdin = io::stdin();
|
||||||
let listener = UnixListener::bind(SOCKET_PATH)?;
|
let mut stdin = stdin.lock();
|
||||||
println!("Server listening on {}", SOCKET_PATH);
|
let mut stdout = io::stdout();
|
||||||
|
|
||||||
|
let d = vec![
|
||||||
|
0x05, // port_len: 5
|
||||||
|
b'C', b'O', b'M', b'1', 0x00, // Port: "COM1" + null终止符(假设)
|
||||||
|
0x00, 0x00, 0x25, 0x80, // baudrate: 9600 (大端)
|
||||||
|
0x01, // stopbits: 1
|
||||||
|
0x00, // parity: 0
|
||||||
|
0x00, 0x00, 0x03, 0xE8, // timeout: 1000 (大端)
|
||||||
|
];
|
||||||
|
|
||||||
|
let c = codec::parse_serial_config(&d).unwrap();
|
||||||
|
println!("{:?}", c);
|
||||||
|
|
||||||
|
let s = String::from_utf8(c.port.clone()).unwrap();
|
||||||
|
println!("port: {}", s);
|
||||||
|
|
||||||
|
println!("port: {:?}", c.port);
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// 接受新连接
|
// 1. 读取4字节长度前缀 (big-endian)
|
||||||
let (stream, _addr) = listener.accept().await?;
|
let mut len_bytes = [0u8; 2];
|
||||||
println!("New client connected");
|
if stdin.read_exact(&mut len_bytes).is_err() {
|
||||||
|
// 读取失败或EOF退出
|
||||||
|
process::exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
// 为每个连接创建异步任务
|
let length = u16::from_be_bytes(len_bytes) as usize;
|
||||||
tokio::spawn(async move {
|
// 2. 读取实际数据
|
||||||
handle_client(stream).await.unwrap_or_else(|e| {
|
let mut data = vec![0u8; length];
|
||||||
eprintln!("Client error: {}", e);
|
if stdin.read_exact(&mut data).is_err() {
|
||||||
});
|
process::exit(-1);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
match data[0] {
|
||||||
|
0x01 => {
|
||||||
|
let config = codec::parse_serial_config(&data[1..]).unwrap();
|
||||||
|
println!("{:?}", config)
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// let data_str = String::from_utf8(data).unwrap_or_else(|_| {
|
||||||
|
// eprintln!("Invalid UTF-8 data");
|
||||||
|
// process::exit(-1);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // 3. 处理数据并生成响应
|
||||||
|
// let response = format!("Processed: {}", data_str);
|
||||||
|
// let response_bytes = response.as_bytes();
|
||||||
|
//
|
||||||
|
// // 4. 写入响应(长度前缀 + 数据)
|
||||||
|
// stdout.write_all(&(response_bytes.len() as u32).to_be_bytes())?;
|
||||||
|
// stdout.write_all(response_bytes)?;
|
||||||
|
// stdout.flush()?; // 确保立即发送
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_client(mut stream: UnixStream) -> Result<(), Box<dyn std::error::Error>> {
|
async fn handle_client(mut stream: UnixStream) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let len = stream.read_u16().await.unwrap();
|
loop {
|
||||||
let mut buf = vec![0u8; len as usize];
|
let len = stream.read_u16().await.unwrap();
|
||||||
|
let mut buf = vec![0u8; len as usize];
|
||||||
|
|
||||||
match stream.read_exact(&mut buf).await {
|
match stream.read_exact(&mut buf).await {
|
||||||
Ok(_) => {
|
Ok(bytes) => {
|
||||||
|
let str = String::from_utf8(buf).unwrap();
|
||||||
},
|
println!("read bytes: {}", str)
|
||||||
Err(err) => {
|
},
|
||||||
println!("read data get error: {}", err)
|
Err(err) => {
|
||||||
|
println!("read data get error: {}", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user