IRC 服务器不响应 Rust IRC 客户端识别请求
IRC server doesn't respond to Rust IRC Client identify requests
我正在使用标准库中的 TcpStream 开发 IRC 机器人。
我能够阅读输入的所有行,但 IRC 服务器似乎没有响应我的身份请求。我以为我发送请求的时间太早了,所以我尝试在发送 IDENT 之前先睡觉,但这不起作用。我使用 BufReader
、BufWriter
和直接在流上调用 read
和 write
来编写,但无济于事。
use std::net::TcpStream;
use std::io::{BufReader, BufWriter, BufRead, Write, Read};
use std::{thread, time};
struct Rusty {
name: String,
stream: TcpStream,
reader: BufReader<TcpStream>,
writer: BufWriter<TcpStream>,
}
impl Rusty {
fn new(name: &str, address: &str) -> Rusty {
let stream = TcpStream::connect(address).expect("Couldn't connect to server");
let reader = BufReader::new(stream.try_clone().unwrap());
let writer = BufWriter::new(stream.try_clone().unwrap());
Rusty {
name: String::from(name),
reader: reader,
writer: writer,
stream: stream,
}
}
fn write_line(&mut self, string: String) {
let line = format!("{}\r\n", string);
&self.writer.write(line.as_bytes());
}
fn identify(&mut self) {
let nick = &self.name.clone();
self.write_line(format!("USER {} {} {} : {}", nick, nick, nick, nick));
self.write_line(format!("NICK {}", nick));
}
fn read_lines(&mut self) {
let mut line = String::new();
loop {
self.reader.read_line(&mut line);
println!("{}", line);
}
}
}
fn main() {
let mut bot = Rusty::new("rustyrusty", "irc.rizon.net:6667");
thread::sleep_ms(5000);
bot.identify();
bot.read_lines();
}
阅读我们在编程时使用的组件的文档非常重要。例如,BufWriter
的文档指出(强调我的):
Wraps a writer and buffers its output.
It can be excessively inefficient to work directly with something that
implements Write
. For example, every call to write on TcpStream
results in a system call. A BufWriter
keeps an in-memory buffer of
data and writes it to an underlying writer in large, infrequent
batches.
The buffer will be written out when the writer is dropped.
换句话说,缓冲 reader 或写入器的 全部目的 是 read
或 write
请求 不要与底层流有一对一的映射。
这意味着当您调用 write
时,您只是将 写入缓冲区 。如果需要确保将字节写入基础流,还需要调用 flush
。
此外,您应该:
- 处理
read
、write
和 flush
可能引起的错误。
- 重新熟悉每个函数的作用。例如,
read
和 write
不保证它们会按照您的要求读取或写入尽可能多的数据。他们可能会执行部分读取或写入,由您来处理。这就是为什么有像 read_to_end
或 write_all
. 这样的辅助方法的原因
- 清除您正在阅读的
String
。否则每次循环都会重复输出。
- 使用
write!
而不是构建一个立即被丢弃的字符串。
fn write_line(&mut self, string: &str) {
write!(self.writer, "{}\r\n", string).unwrap();
self.writer.flush().unwrap();
}
通过这些更改,我能够从服务器获得 PING
消息。
我正在使用标准库中的 TcpStream 开发 IRC 机器人。
我能够阅读输入的所有行,但 IRC 服务器似乎没有响应我的身份请求。我以为我发送请求的时间太早了,所以我尝试在发送 IDENT 之前先睡觉,但这不起作用。我使用 BufReader
、BufWriter
和直接在流上调用 read
和 write
来编写,但无济于事。
use std::net::TcpStream;
use std::io::{BufReader, BufWriter, BufRead, Write, Read};
use std::{thread, time};
struct Rusty {
name: String,
stream: TcpStream,
reader: BufReader<TcpStream>,
writer: BufWriter<TcpStream>,
}
impl Rusty {
fn new(name: &str, address: &str) -> Rusty {
let stream = TcpStream::connect(address).expect("Couldn't connect to server");
let reader = BufReader::new(stream.try_clone().unwrap());
let writer = BufWriter::new(stream.try_clone().unwrap());
Rusty {
name: String::from(name),
reader: reader,
writer: writer,
stream: stream,
}
}
fn write_line(&mut self, string: String) {
let line = format!("{}\r\n", string);
&self.writer.write(line.as_bytes());
}
fn identify(&mut self) {
let nick = &self.name.clone();
self.write_line(format!("USER {} {} {} : {}", nick, nick, nick, nick));
self.write_line(format!("NICK {}", nick));
}
fn read_lines(&mut self) {
let mut line = String::new();
loop {
self.reader.read_line(&mut line);
println!("{}", line);
}
}
}
fn main() {
let mut bot = Rusty::new("rustyrusty", "irc.rizon.net:6667");
thread::sleep_ms(5000);
bot.identify();
bot.read_lines();
}
阅读我们在编程时使用的组件的文档非常重要。例如,BufWriter
的文档指出(强调我的):
Wraps a writer and buffers its output.
It can be excessively inefficient to work directly with something that implements
Write
. For example, every call to write onTcpStream
results in a system call. ABufWriter
keeps an in-memory buffer of data and writes it to an underlying writer in large, infrequent batches.The buffer will be written out when the writer is dropped.
换句话说,缓冲 reader 或写入器的 全部目的 是 read
或 write
请求 不要与底层流有一对一的映射。
这意味着当您调用 write
时,您只是将 写入缓冲区 。如果需要确保将字节写入基础流,还需要调用 flush
。
此外,您应该:
- 处理
read
、write
和flush
可能引起的错误。 - 重新熟悉每个函数的作用。例如,
read
和write
不保证它们会按照您的要求读取或写入尽可能多的数据。他们可能会执行部分读取或写入,由您来处理。这就是为什么有像read_to_end
或write_all
. 这样的辅助方法的原因
- 清除您正在阅读的
String
。否则每次循环都会重复输出。 - 使用
write!
而不是构建一个立即被丢弃的字符串。
fn write_line(&mut self, string: &str) {
write!(self.writer, "{}\r\n", string).unwrap();
self.writer.flush().unwrap();
}
通过这些更改,我能够从服务器获得 PING
消息。