chore: add gitignore

This commit is contained in:
michel
2024-09-09 08:32:51 +02:00
committed by Michel de Graaf
parent 5c56066960
commit d67ed4742a
2 changed files with 216 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
/target
+215
View File
@@ -0,0 +1,215 @@
Additional context is provided below.
I have the following from soulseek_download/src/main.rs:
```rust
use std::collections::VecDeque;
use std::io::{self, Write};
use std::net::{TcpStream, ToSocketAddrs};
use std::sync::{Arc, Barrier, Condvar, Mutex};
use std::thread::{self, sleep};
use std::time::Duration;
mod buffered_reader;
mod message;
mod message_factory;
#[derive(Debug, Clone)]
struct ServerAddress {
host: String,
port: u16,
}
struct Client {
address: ServerAddress,
username: String,
password: String,
}
struct Server {
address: ServerAddress,
stream: Arc<Mutex<TcpStream>>,
message_queue: Arc<(Mutex<VecDeque<Vec<u8>>>, Condvar)>,
}
impl Server {
/// Create a new instance of Server, returning a Result
fn new(address: ServerAddress) -> Result<Self, io::Error> {
println!("Connecting to server at {}:{}", address.host, address.port);
// Convert the host and port into a socket address
let socket_address = format!("{}:{}", address.host, address.port)
.to_socket_addrs()?
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "Invalid address"))?;
// Establish the connection with a timeout
let stream = TcpStream::connect_timeout(&socket_address, Duration::from_secs(10))?;
// Set the stream to non-blocking mode if needed or configure timeouts
stream.set_read_timeout(Some(Duration::from_secs(5)))?;
stream.set_write_timeout(Some(Duration::from_secs(5)))?;
let message_queue = Arc::new((Mutex::new(VecDeque::new()), Condvar::new())); // Initialize the message queue with Condvar
let server = Self {
address,
stream: Arc::new(Mutex::new(stream)),
message_queue,
};
server.start_read_write_loops();
Ok(server)
}
/// Start reading and writing loops in separate threads
fn start_read_write_loops(&self) {
// Create a channel to send messages to the write thread
let read_stream = Arc::clone(&self.stream);
let write_stream = Arc::clone(&self.stream);
let barrier = Arc::new(Barrier::new(2));
let read_barrier = barrier.clone();
let write_barrier = barrier.clone();
let message_queue = self.message_queue.clone();
// Spawn a thread to handle reading from the server
thread::spawn(move || {
read_barrier.wait();
let mut buffered_reader = buffered_reader::BufferedReader::new();
loop {
match buffered_reader.read_from_socket(&mut read_stream.lock().unwrap()) {
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
Err(ref e) if e.kind() == io::ErrorKind::TimedOut => {
println!("Read operation timed out");
continue;
}
Err(e) => {
eprintln!("Error reading from server: {}", e);
break;
}
}
match buffered_reader.extract_message() {
Ok(Some(mut message)) => {
println!("Received message: {:?}", message.get_data());
self.handle_message(&mut message);
}
Err(e) => {
println!("Error extracting message: {}", e)
}
Ok(None) => continue,
}
}
});
thread::spawn(move || {
write_barrier.wait();
loop {
let (lock, cvar) = &*message_queue;
let mut queue = lock.lock().unwrap();
// Wait for a message to be added to the queue
while queue.is_empty() {
queue = cvar.wait(queue).unwrap();
}
// Pop and send the message
if let Some(message) = queue.pop_front() {
match write_stream.lock().unwrap().write_all(&message) {
Ok(_) => println!("Sent buffered message: {:?}", message),
Err(e) => {
eprintln!("Failed to send buffered message: {}", e);
// Handle error appropriately
break;
}
}
}
}
});
}
fn queue_message(&self, message: Vec<u8>) {
let (lock, cvar) = &*self.message_queue;
let mut queue = lock.lock().unwrap();
queue.push_back(message);
cvar.notify_one();
}
fn login(&mut self, username: &str, password: &str) -> Result<(), std::io::Error> {
self.queue_message(message_factory::build_init_message().get_data());
self.queue_message(message_factory::build_login_message(username, password).get_data());
Ok(())
}
fn handle_message(&mut self, message: &mut message::Message) {
let code = message.get_code();
match code {
1 => {
println!("Received login response");
let response = message.read_int8();
if response == 1 {
println!("Login successful");
} else {
println!("Login failed");
}
}
_ => {
println!("Received unknown message with code {}", code);
}
}
}
}
impl Client {
fn new(address: ServerAddress, username: String, password: String) -> Self {
Self {
address,
username,
password,
}
}
fn connect(&self) {
// Attempt to create a server instance
match Server::new(self.address.clone()) {
Ok(mut server) => {
println!(
"Connected to server at {}:{}",
server.address.host, server.address.port
);
// Attempt to login
println!("Logging in as {}", self.username);
if let Err(e) = server.login(&self.username, &self.password) {
eprintln!("Error during login: {}", e);
}
}
Err(e) => eprintln!("Error connecting to server: {}", e),
}
}
}
// ServerAddress {
// host: String::from("server.slsknet.org"),
// port: 2242,
// },
fn main() {
let client = Client::new(
ServerAddress {
// host: String::from("server.slsknet.org"),
host: String::from("localhost"),
port: 2242,
},
String::from("insane_in_the_brain2"),
String::from("invalid"),
// String::from("13375137"),
);
client.connect();
loop {
thread::park();
}
}
```