从streambuffer中提升异步读写异常数据
Boost asynchronous read and write weird data from streambuffer
我正在使用boost异步读写我的微控制器。我安装了我的微控制器,这样它就可以读取异步写入发送的数据,并将其返回到计算机,在计算机中,计算机通过单个线程上的异步读取来读取数据。我把"15"发送到微控制器。插入微控制器后的每次第一次发送都工作良好,但在此之后,它会偶尔从串行端口"f"answers"?f15"读取"。无论何时f或?f15被发送,7个字节在回调中被传输,这对我来说意义不大,因为f只是一个ascii值。这是我的客户端串行端口包装代码:
void Serial::async_write(std::string string){
std::cout << "String size:" << string.size() << std::endl;
// char stringToChar[string.size() + 1];
// strcpy(stringToChar, string.c_str());
// this->async_write(stringToChar);
boost::asio::async_write(*port_, boost::asio::buffer(string, string.length()), boost::bind(&Serial::async_write_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void Serial::async_write_buffer(std::vector<char> data){
int num = data.size();
std::cout << num << std::endl;
boost::asio::mutable_buffer buf(&data, data.size());
boost::asio::async_write(*port_, boost::asio::buffer(data, data.size()), boost::bind(&Serial::async_write_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void Serial::async_write_handler(const boost::system::error_code &e, std::size_t bytes_written){
std::cout << "Data written" << std::endl;
//b_->consume(bytes_written);
}
void Serial::async_read_handler(const boost::system::error_code &e, std::size_t bytes_read){
if(!(*e)){
std::cout << "bytes read in async read handler:" << bytes_read << std::endl;
if(bytes_read > 0){
b_->commit(bytes_read);
std::istream* instream = new std::istream(b_);
std::string streamtostring;
*instream >> streamtostring;
std::cout << "size of input buffer:" << b_->size() << std::endl;
std::cout << "Read: " <<std::endl;
b_->consume(bytes_read);
std::cout << streamtostring << std::endl;
}
else{
std::cout << "No bytes read" << std::endl;
}
}
else{
std::cout << "Error occurred!" << std::endl;
std::cerr << e.message() << std::endl;
}
}
void Serial::async_read_until(std::string delim){
boost::system::error_code e;
boost::asio::async_read_until(*port_, *b_, delim, boost::bind(&Serial::async_read_handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
这是在main.cpp中调用它的代码:
int main(){
boost::asio::io_service io;
Serial::Serial serial(PORT, &io, 9600);
if(!serial.is_open()){
serial.open(PORT);
}
std::string s = "15";
serial.async_write(s);
serial.async_read_until("n");
// const char arr[] = {'2', '5', '5'};
// serial.async_write(arr);
// std::string s = "50089q503320232500202";
// std::vector<char> data(s.begin(), s.end());
// serial.async_write_buffer(data);
io.run();
}
现在在微控制器方面,我让它将每个传入的数据字节放入一个字符的stackArray中,然后将它们一个接一个地弹出到一个比堆栈数组多1个字符长的字符数组中。由于异步读取一直读到换行符,所以我在字符数组的最后插入一个换行符。然后我把它送过小溪。
#include <StackArray.h>
StackArray<int> binary;
int ledPin = 13;
int numberOfExecs = 0;
byte data = 0;
void setup() {
Serial.begin(9600);
//binary.setPrinter(Serial);
pinMode(ledPin, OUTPUT);
}
void blink(int times, int duration){
for(int i = 0; i < times; i++){
digitalWrite(ledPin, HIGH);
delay(duration);
digitalWrite(ledPin, LOW);
delay(duration);
}
}
void loop() {
//get number of bytes waiting in the serial buffer
int bytesWaiting = Serial.available();
//create array of character values
StackArray<char> letterVals;
//Set the printer for the stack array to serial
letterVals.setPrinter(Serial);
//while serial is available, push each byte of data to the stack array
while(Serial.available() > 0){
byte data = Serial.read();
char c = data;
//Serial.println(c);
letterVals.push(c);
// convertToBinary(data, binary);
// printToLED(binary);
}
//Get the number of elements in the stack array
int numElements = letterVals.count();
//indicate how many elements there are on the led
blink(numElements, 1000);
// blink(1, 5000);
//length of array
int len = numElements + 1;
//create array to send back data
char sendback[len];
if(bytesWaiting > 0){
for(int i = len - 2; i >= 0; i--){
//pop each character into its original position
int asciiVal = letterVals.pop();
//blink(asciiVal, 350);
//blink(20, 20);
sendback[i] = asciiVal;
}
}
//set last character to newline
sendback[len - 1] = 10;
//if there are no bytes available to read, send off data
if(bytesWaiting > 0){
Serial.println(sendback);
}
}
有人知道为什么随机f和吗?f一直出现吗?谢谢
这可能是客户端代码调用未定义行为的结果。具体来说,该代码无法满足boost::asio::async_write()
的buffers
参数的生存期要求
[…]底层内存块的所有权由调用者保留,调用者必须保证它们在调用处理程序之前保持有效。
在Serial::async_write()
和Serial::async_write_buffer()
中,作为缓冲区提供的底层内存由一个对象所有,该对象的生存期在函数返回后结束。由于这两个函数都不能保证它们在调用async_write
的完成处理程序之前不会返回,因此临时函数的生存期违反了async_write()
的要求,导致了未定义的行为。
void Serial::async_write(std::string string)
{
boost::asio::async_write(
...,
boost::asio::buffer(string, string.length()),
...);
} // `string`'s lifetime ends.
void Serial::async_write_buffer(std::vector<char> data)
{
boost::asio::async_write(
...,
boost::asio::buffer(data, data.size()),
...);
} // `data`'s lifetime ends.
相关文章:
- 用C++快速读写文件
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 在一个读写器队列中,我可以用volatile替换原子吗
- C++套接字对不读/写父/子
- 如何调试读写器锁的死锁?
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- Linux 挂载使用重新挂载以允许读写
- C++中读/写二进制文件
- 如何读/写或遍历 std::array 中的特定元素范围?
- 内存排序或读取-修改-写入操作,仅(读/写)内存顺序
- USB-HID 读/写(重叠)等待单个对象不返回C++
- 为什么使用_access时只读测试对读写文件有效
- Boost::Asio串行读/写打开:参数不正确
- 读/写 OpenMP 中的共享向量会减慢程序速度
- 谷歌测试读写同一文件失败
- Android USB 附件模式无法使用 libusb 与主机 PC 一起读/写
- 特定时间间隔 C++ 上的读写日志
- 从streambuffer中提升异步读写异常数据
- 内存读/写错误异常