关于ReadFile读数据读不完整的问题

Avenger_M 2014-09-01 10:42:00
字节写了一个测试程序,通过COM4给COM1发送20个字节的数据,但是如果循环发送且发送很频繁的时候,会经常出现20个字节要执行两次Uart_Read函数才能收完,试过了各种方法,仍然没有解决,请各位高手帮助:
以下是我封装的串口接受函数:

static COMSTAT ms_ComStat; // 串口状态

static OVERLAPPED ms_Ov;

int Uart_Read(HANDLE hComm, unsigned char *rbuf, int *len)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
int rtn = 0;
BYTE tmpbuf[256];
DWORD nPos = 0;
DWORD readcnt = 0; // 读到数据次数

memset(tmpbuf, 0x00, sizeof(256));

for(;;)
{
bResult = ClearCommError(hComm, &dwError, &ms_ComStat);
if ( ms_ComStat.cbInQue == 0 )
{
if( readcnt == 0 )
{
return -1;
}
else
{
memcpy(len, &nPos, sizeof(int));
printf("[Uart_Read]nPos is %d, readcnt is %d\r\n", nPos, readcnt);
return 0;
}
}

printf("[Uart_Read]cbInQue is %d\r\n", ms_ComStat.cbInQue);

if ( bRead )
{
bResult = ReadFile(hComm, // Handle to COMM port
tmpbuf, // RX Buffer Pointer
ms_ComStat.cbInQue, // Read one byte
&BytesRead, // Stores number of bytes read
NULL); // pointer to the m_ov structure
if ( !bResult )
{
rtn = -1;
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
bRead = FALSE;
break;
}
default:
{
break;
}
}
}
else
{
bRead = TRUE;
readcnt++;
memcpy(&rbuf[nPos], tmpbuf, ms_ComStat.cbInQue);
nPos += ms_ComStat.cbInQue;
}
} // close if (bRead)

if ( !bRead )
{
bRead = TRUE;
bResult = GetOverlappedResult(hComm, // Handle to COMM port
&ms_Ov, // Overlapped structure
&BytesRead, // Stores number of bytes read
TRUE); // Wait flag
}
}
}


以下是调用的地方:
static HANDLE ms_hcomm = NULL;
int _tmain(int argc, _TCHAR* argv[])
{
int bufLen = 0;
unsigned char buf[256] = {0};
//wchar_t *cComName = _T("COM1");
char *cComName = "COM1";

Uart_Init();
ms_hcomm = Uart_Open((char *)cComName);
if( !Uart_IsOpen(ms_hcomm) )
{
if( !Uart_SetTimeout(ms_hcomm, MAXDWORD, 0, 0, 0, 0) )
{
printf("[_tmain] SetTimeout ok\r\n");
}
Uart_SetDcb(ms_hcomm, CBR_9600, EVENPARITY, ONESTOPBIT, 8);
//SetCommMask(ms_hcomm, EV_RXCHAR);//当有字符在inbuf中时产生这个事件

while(1)
{
if( !Uart_Read(ms_hcomm, buf, &bufLen) )
{
printf("buf addr is %08x, buflen is %d:", buf, bufLen);
for(int i=0; i<bufLen; i++)
{
printf("%02x ", buf[i]);
}
printf("\r\n");
}
Sleep(50);
}
}
return 0;
}


以下是输出结果:
[_tmain] SetTimeout ok
[Uart_Read]cbInQue is 16
[Uart_Read]cbInQue is 4
[Uart_Read]nPos is 20, readcnt is 2
buf addr is 0012fe54, buflen is 20:11 22 33 44 55 66 77 88 99 00 11 22 33 44 55
66 77 88 99 00
[Uart_Read]cbInQue is 16
[Uart_Read]nPos is 16, readcnt is 1
buf addr is 0012fe54, buflen is 16:11 22 33 44 55 66 77 88 99 00 11 22 33 44 55
66
[Uart_Read]cbInQue is 4
[Uart_Read]nPos is 4, readcnt is 1
buf addr is 0012fe54, buflen is 4:77 88 99 00
...全文
501 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-09-03
  • 打赏
  • 举报
回复
推荐使用PortMon软件辅助调试串口通讯相关程序。
赵4老师 2014-09-03
  • 打赏
  • 举报
回复
推荐使用FileMon软件辅助调试文件读写相关功能。
zilaishuichina 2014-09-02
  • 打赏
  • 举报
回复
引用 9 楼 u010848119 的回复:
引用 8 楼 zhao4zhong1 的回复:
任何通讯机制,收方收得太慢都会导致发方发的速度受阻或发的数据丢失。
我是循环接收的,有数据应该是立刻接收,希望赵老师能深入指点。
再怎么循环,Read之后的操作总是要花时间的,你不可能保证Write和Read一定能保持同样的速率,
Avenger_M 2014-09-02
  • 打赏
  • 举报
回复
引用 7 楼 zxh707wk 的回复:
一次不能发多点吗
20个字节是为了测试基本功能用,发的越多,数据收不全的问题出现几率越大。
Avenger_M 2014-09-02
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
任何通讯机制,收方收得太慢都会导致发方发的速度受阻或发的数据丢失。
我是循环接收的,有数据应该是立刻接收,希望赵老师能深入指点。
熊熊大叔 2014-09-02
  • 打赏
  • 举报
回复
如果你学习过通信中的OSI 7层协议模型,就很容易理解了。 底层的串口通信就相当于物理层,每帧20字节或者更多字节,是数据链路层的事,这是你的程序自己要处理的。你自己的程序要不断读,然后按照每20字节(或者其他定帧方法)进行重组,底层是不可能保证发送的20字节一定一次性收到的。
Avenger_M 2014-09-01
  • 打赏
  • 举报
回复
希望有人能够指点迷津
Avenger_M 2014-09-01
  • 打赏
  • 举报
回复
希望有人能够指点迷津
Avenger_M 2014-09-01
  • 打赏
  • 举报
回复
希望有人能够指点迷津
赵4老师 2014-09-01
  • 打赏
  • 举报
回复
任何通讯机制,收方收得太慢都会导致发方发的速度受阻或发的数据丢失。
707wk 2014-09-01
  • 打赏
  • 举报
回复
一次不能发多点吗
龍之印 2014-09-01
  • 打赏
  • 举报
回复
关注此问题!
龍之印 2014-09-01
  • 打赏
  • 举报
回复
关注此问题!
龍之印 2014-09-01
  • 打赏
  • 举报
回复
关注此问题!

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧