read()不返回指定的字节数

时间:2014-05-22 15:34:48

标签: c++ linux

我正在阅读带有read()功能的传感器数据(在RS232上广播)。数据速率为264字节/秒。

我使用以下代码来读取数据(我只需要读取60个字节)。

int BytesToRead = 60;
unsigned char* iBuffer = new unsigned char[BytesToRead];
int ret = read(COM, iBuffer, BytesToRead);

cout<<ret<<endl;    

if (ret == 0) {
cout<<"Error Reading COM Port"<<endl;
exit(EXIT_FAILURE);         // Error Handling
} 
delete[] iBufer;

此程序返回随机字节(~30)。

我是C ++编程的初学者。对不起,如果我犯了一些愚蠢的错误。

感谢。

我的COM功能:

int Connect(const char *DeviceName){

long BAUD = B115200;
long DATABITS = CS8;            // CS8 = 8n1 Config.(8 bits, No parity, 1 Stop Bit)
long VMIN_CC = 1;           // 1 input byte is enough to return from read()
long VTIME_CC = 0;          // Inter-character timer
long STOPBITS = 0;          // Defined with CS8
long PARITYON = 0;          // NONE (Ref.: IH2 Azzura Hand User Guide)
long PARITY = 0;            // NONE (Ref.: IH2 Azzura Hand User Guide)


struct termios config;          // Configuration of the termios structure
fd_set rdset;               // File discription set

//Basic serial interface configuration  
//iflag = Input flag || oflag = Output flag || lflag = No-line processing flag
//c_cflag = Caracter processing flag || c_cc = Special character flag

memset(&config,0,sizeof(config));
config.c_iflag = 0;             // Turning OFF Input processing
config.c_oflag = 0;             // Turning OFF Output processing
config.c_lflag = 0; 
config.c_cflag = DATABITS |CREAD|CLOCAL;// Enable the receiver and set local mode
config.c_cc[VMIN] = VMIN_CC;        
config.c_cc[VTIME] = VTIME_CC;      

//Opening the Port for communication
int com = open(DeviceName, O_RDWR | O_NOCTTY);

//Error Handling    
if (com < 0) {
cout<<"ERROR!! Opening Port \n"<<"Sys:"<<strerror(errno)<<endl;
exit(EXIT_FAILURE);
} else {cout<<"Serial Communication (Opening Port): "<<strerror(errno)<<endl;}

//Setting the BaudRate for Communcation
cfsetispeed(&config, BAUD);
cfsetospeed(&config, BAUD);

//Applying Configuration / Attributes
int Attr = tcsetattr(com, TCSANOW, &config);

//Error Handling
if(Attr < 0){
    cout<<"ERROR!! Setting Attributes \n"<<"Sys:"<< strerror(errno)<<endl;
    exit(EXIT_FAILURE);
    } else {cout<<"Serial Communication (Setting Attributes): "<<strerror(errno)<<endl;}

return(com);

}

2 个答案:

答案 0 :(得分:4)

我假设这是一个Linux系统.... 你的BytesToRead变量只是read()的一个建议,read()将尝试读取BytesToRead。如果read()返回的数量少于您请求的数量,则可以读取的字节数减少。 从linux手册页上阅读

  

...如果此数字小于请求的字节数,则不是错误;这可能发生在例如因为现在实际可用的字节数较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为read()被中断了信号...

您的传感器可能没有发送您期望的数据,或者您没有给它足够的时间来传输所有数据,或者您的代码示例中还有一些其他逻辑/硬件问题并不明显。

答案 1 :(得分:1)

read()无法保证返回请求的字节数:

来自read(2) Linux联机帮助页:

  

成功时,返回读取的字节数(零表示文件结束),文件位置按此编号前进。如果此数字小于请求的字节数,则不是错误;这可能发生在例如因为现在实际可用的字节数较少(可能是因为我们接近文件结尾,或者因为我们正在从管道或终端读取),或者因为read()被中断了信号。出错时,返回-1,并正确设置errno。在这种情况下,未指定文件位置(如果有)是否发生变化。