高手帮我看一下这个线程的源码!

无理蛇 2005-09-20 10:40:32
我现在是用两个串口去监视另一个串口与仪器的通讯,一个监视读的数据,一个监视写的数据。

现在有两个问题:
1、我在线程中用下面的代码实现停止线程,关闭串口,可是为什么我用COM1和COM2来进行监视的时候没有问题,可用COM1和COM5进行监视就有问题,停止后要再打开串口进行监视,发现打不开串口,COM1
和COM5都打不开?
if (Terminated)
{
PurgeComm(m_hComm1, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
PurgeComm(m_hComm2, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

if (m_hComm1 != NULL)
{
if (!CloseHandle(m_hComm1))
ShowMessage("CloseHandle1 Error!");
m_hComm1 = NULL;
}
if (m_hComm2 != NULL)
{
if (!CloseHandle(m_hComm2))
ShowMessage("CloseHandle1 Error!");
m_hComm2 = NULL;
}
break;
}
2、为什么有的长的数据要分好几次收?
比如我发了两次数据“ksdjflsajfd"和”ldsajfldsajfd",可是在监视的数据中可能变成“ksdj”、“flsajfdldsajfld”、“sajfd”这样子三段数据,为什么?



线程源码(主要的循环)

for(;;)
{
OVERLAPPED os,READ_OS;
memset(&os,0,sizeof(os));
os.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL);

WaitCommEvent(m_hComm1,&dwEvtMask, &os);
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
COMSTAT ComStat ;
DWORD dwLength ;
DWORD dwErrorFlags;
DWORD dwBytesRead;
DWORD dwError;

ClearCommError(m_hComm1,&dwErrorFlags,&ComStat );
dwLength = ComStat.cbInQue ;
READ_OS.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL);
if (dwLength>0)
{
BOOL fReadStat;
int i,iCount=0;
for (i=1;i<=dwLength;i++)
{
fReadStat =ReadFile(m_hComm1, lpBuffer,1,&dwBytesRead,&READ_OS);
if (StrLen(lpBuffer)==0)
lpData[iCount]='\0';
else
lpData[iCount]=lpBuffer[0];
iCount++;
}
if (fReadStat)
{
HANDLE hWndMain=FindWindow(NULL, "Port MonitorII V1.0");

COPYDATASTRUCT cdsMain;
cdsMain.dwData=sizeof(COPYDATASTRUCT);
cdsMain.cbData=dwLength;
cdsMain.lpData=(char *)lpData;

SendMessage(hWndMain,WM_COPYDATA,1,(LPARAM)&cdsMain);
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hComm1,&READ_OS,& dwBytesRead, TRUE ))
{
dwError = GetLastError();
if (dwError == ERROR_IO_INCOMPLETE) continue;
}
}
}
}
}

WaitCommEvent(m_hComm2,&dwEvtMask, &os);
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
COMSTAT ComStat ;
DWORD dwLength ;
DWORD dwErrorFlags;
DWORD dwBytesRead;
DWORD dwError;

ClearCommError(m_hComm2,&dwErrorFlags,&ComStat );
dwLength = ComStat.cbInQue ;
READ_OS.hEvent =CreateEvent(NULL,TRUE,FALSE,NULL);
if (dwLength>0)
{
BOOL fReadStat;
int i,iCount=0;
for (i=1;i<=dwLength;i++)
{
fReadStat =ReadFile(m_hComm2, lpBuffer,1,&dwBytesRead,&READ_OS);
if (StrLen(lpBuffer)==0)
;
else
lpData[iCount]=lpBuffer[0];
iCount++;
}
if (fReadStat)
{
HANDLE hWndMain=FindWindow(NULL, "Port MonitorII V1.0");

COPYDATASTRUCT cdsMain;
cdsMain.dwData=sizeof(COPYDATASTRUCT);
cdsMain.cbData=dwLength;
cdsMain.lpData=(char *)lpData;

SendMessage(hWndMain,WM_COPYDATA,2,(LPARAM)&cdsMain);
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hComm2,&READ_OS,& dwBytesRead, TRUE ))
{
dwError = GetLastError();
if (dwError == ERROR_IO_INCOMPLETE) continue;
}
}
}
}
}
if (Terminated)
{
PurgeComm(m_hComm1, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
PurgeComm(m_hComm2, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

if (m_hComm1 != NULL)
{
if (!CloseHandle(m_hComm1))
ShowMessage("CloseHandle1 Error!");
m_hComm1 = NULL;
}
if (m_hComm2 != NULL)
{
if (!CloseHandle(m_hComm2))
ShowMessage("CloseHandle1 Error!");
m_hComm2 = NULL;
}
break;
}
Sleep(1);
Application->ProcessMessages();
}
...全文
361 4 打赏 收藏 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
lhj 2005-12-16
  • 打赏
  • 举报
回复
问题1,要确认机器上有没有COM5
问题2,基于流的通讯都会可能存在这种情况。即不是一次收完全部数据。
1次发送,可能分成多次接收才完成。
多次发送,一次完成
m次发送,n次收完都是可能发生的情况。
出现这种情况的解决办法
1,是降低收发速度
2,是自己定义协议,自己断包。最简单的就是先发2个字节长度,然后跟着对应长度的包体。接收时先收2字节长度,然后继续接收指定长度的数据,认为一个包结束。收下一个包又是先收2字节长度。
rudolf_he 2005-12-05
  • 打赏
  • 举报
回复
不明白,就两个串口的通讯也要用到多线程?

放两个串口通讯控件,分别在相应的事件里去处理不就成了?
jamesband031 2005-12-04
  • 打赏
  • 举报
回复
帮顶

--------签名档----------------------------

号外号外,新鲜的酷站大出炉,不买也看看啊:*)

www.source520.com

80G源码电子书免费免注册下载,大量精辟技术文档库随时更新
zz997788 2005-12-01
  • 打赏
  • 举报
回复
学习一下

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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