while (respond.find(“----more----”) == std::string::npos) {
// 在循环内部处理 respond 的逻辑
// …
// 更新 respond 的值
// 假设有一些方法或逻辑来获取新的 respond 值
read(fd,buf,100);
respond(buf,len);
}
// 创建消息处理对象
MessageHandler handler;
SwitchMonitor switchMonitor(handler, “/dev/ttyUSB0”);
ClientMonitor clientMonitor(handler, “/dev/ttyUSB1”);
void function() {
std::mutex Mutex;
std::lock_guardstd::mutex lock(Mutex);
}
handler这个全局的类变量在其他类线程中使用,在每个线程中上锁,锁可以用std::mutex Mutex;局部变量的锁吗
std::string serialData;
while (isMonitoring_) {
char buf[1024];
std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
serialData(buf, bytes_read);
while (isMonitoring_) {
char buf[1024];
std::string serialData;
std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
serialData.append(buf, bytes_read);
这种写法每次读到的buf里面是不是有大量的空字符,比如读到username8个字符,剩下的1016个字节应该都是空字符吧,serialData.append会追加很多空字符,打印出来是空白的吧,会这样吗,如果是这样怎么改
std::string serialData;
while (isMonitoring_) {
char buf[1024];
std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
serialData.append(buf, bytes_read);
std::string serialData;这个是定义在while循环外面好还是里面好,每次执行到std::string serialData;定义处都会把它赋空吗,重新赋值吗,覆盖前面的
std::string serialData =R"(
username
password:
Repond login authentication
)";
std::string serialData;
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
serialData(buf, bytes_read);能这样用吗
std::string serialData;
while (isMonitoring_) {
char buf[1024];
std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
serialData.append(buf, bytes_read);
ssize_t bytesWritten = write(m_serialFd, serialData.c_str(), serialData.length());
把读到的写入串口,串口工具回显是这样的,有阶梯,是啥原因:
username:
Error: The username times out.
username:
Error: The username times out.
std::string serialData =R"(
username
Error: The username times out.
Error: The username times out.
)";
这个字符串write写入串口会下面那样回显
username:
Error: The username times out.
username:
Error: The username times out.
// 使用istringstream将字符串拆分为一行一行
std::istringstream stream(serialData);
std::string line;
while (std::getline(stream, line)) {
// 添加换行符
line += '\n';
// 写入串口
ssize_t bytes_written = write(serial_port, line.c_str(), line.size());
if (bytes_written < 0) {
std::cerr << "Error writing to serial port" << std::endl;
close(serial_port);
return 1;
}
}
在串口通信中,当你发送换行符('\n')时,它通常只会将光标移动到下一行,但不会将光标移到行首。如果你希望光标移动到新的一行并且从行首开始显示,你需要发送回车符('\r')和换行符('\n')。
这是因为 ‘\r’ (回车) 将光标移动到当前行的开头,而 ‘\n’ (换行) 将光标移动到下一行。
示例代码修改
你可以在每行数据后添加 ‘\r\n’ 而不是只添加 ‘\n’。以下是修改后的代码:
cpp
#include
#include
#include
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
const char *device = “/dev/ttyS3”; // 替换为实际的串口设备名称
int serial_port = open(device, O_RDWR);
if (serial_port < 0) {
std::cerr << "Error opening serial port" << std::endl;
return 1;
}
// 配置串口参数
termios tty;
if (tcgetattr(serial_port, &tty) != 0) {
std::cerr << "Error getting termios attributes" << std::endl;
close(serial_port);
return 1;
}
cfsetospeed(&tty, B9600); // 设置波特率
cfsetispeed(&tty, B9600);
tty.c_cflag &= ~PARENB; // 清除校验位
tty.c_cflag &= ~CSTOPB; // 设置1个停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 设置8个数据位
tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控
tty.c_cflag |= CREAD | CLOCAL; // 启用读取和忽略调制解调器控制线
tty.c_lflag &= ~ICANON; // 禁用规范模式
tty.c_lflag &= ~ECHO; // 禁用回显
tty.c_lflag &= ~ECHOE; // 禁用回显擦除
tty.c_lflag &= ~ECHONL; // 禁用新行回显
tty.c_lflag &= ~ISIG; // 禁用信号处理
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // 禁用特殊字符处理
tty.c_oflag &= ~OPOST; // 禁用输出处理
tty.c_oflag &= ~ONLCR; // 禁用新行转换
tty.c_cc[VTIME] = 10; // 设置读超时时间
tty.c_cc[VMIN] = 0;
if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
std::cerr << "Error setting termios attributes" << std::endl;
close(serial_port);
return 1;
}
// 准备要写入串口的数据
std::string serialData = R"(
username
Error: The username times out.
Error: The username times out.
)";
// 使用istringstream将字符串拆分为一行一行
std::istringstream stream(serialData);
std::string line;
while (std::getline(stream, line)) {
// 添加回车和换行符
line += "\r\n";
// 写入串口
ssize_t bytes_written = write(serial_port, line.c_str(), line.size());
if (bytes_written < 0) {
std::cerr << "Error writing to serial port" << std::endl;
close(serial_port);
return 1;
}
}
// 读取回显
char buffer[256];
memset(buffer, 0, sizeof(buffer));
ssize_t bytes_read = read(serial_port, buffer, sizeof(buffer) - 1);
if (bytes_read < 0) {
std::cerr << "Error reading from serial port" << std::endl;
close(serial_port);
return 1;
}
// 将读取的数据转换为string并输出
std::string response(buffer, bytes_read);
std::cout << response << std::endl;
// 关闭串口
close(serial_port);
return 0;
}
解释
\r\n:‘\r’ 是回车符,将光标移到当前行的起始位置;‘\n’ 是换行符,将光标移到下一行。因此,“\r\n” 可以确保新的一行从行首开始显示。
通过这种方式,你可以确保在串口工具上看到的输出每行都从行首开始显示。