怎样监视已经打开的串口

cegaryli 2002-11-26 01:20:34
如果一个串口已经被其它程序打开,我怎样在程序中读取(监视)该端口的数据?就象PORTMON一样.
...全文
387 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
cegaryli 2002-12-03
  • 打赏
  • 举报
回复
问题还没有解决!!!!!!!!!
FlyOverSea 2002-12-03
  • 打赏
  • 举报
回复
做个标记 :)
cegaryli 2002-12-02
  • 打赏
  • 举报
回复
请问 nuaawyd(神啊,救救我吧!) :CNcfileCtrlDlg作了什么事?
HuWenjin 2002-12-02
  • 打赏
  • 举报
回复
up
lhynew 2002-12-02
  • 打赏
  • 举报
回复
我也想用hook,怎么hook? yousen(一个人流浪)
linyudie 2002-12-01
  • 打赏
  • 举报
回复
呵呵,sbw(清风一笑) 的主意我倒是真的用过,为了测试的话好像真的挺省事的,:)
不过不用两个机器啊,做一根线,两个头,一般机器都是两个串口么,都插上,只管读
另外一个就可以了,

要是非用driver,wdm的就行了吧,在port class 加一个过滤,我在2K上干过,98应该也没问题,反正不大会有人再坚持用95了吧
qiufuwang 2002-12-01
  • 打赏
  • 举报
回复
up
yousen 2002-12-01
  • 打赏
  • 举报
回复
hook api
直接hook ReadFile,WriteFile不就搞定了
nuaawyd 2002-12-01
  • 打赏
  • 举报
回复
// 工作者线程,负责监视串行口
UINT CommProc(LPVOID pParam)
{
OVERLAPPED os;
DWORD dwMask, dwTrans;
COMSTAT ComStat;
DWORD dwErrorFlags;
CNcfileCtrlDlg *pDoc = (CNcfileCtrlDlg*)pParam;
memset(&os, 0, sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
if(os.hEvent == NULL)
{
::MessageBox(NULL,"不能创建事件对象!","警告",
MB_ICONWARNING | MB_OK);
return (UINT)-1;
}
while(pDoc->m_bConnected)
{
ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
if(ComStat.cbInQue)
{
// 无限等待WM_COMMNOTIFY消息被处理完
WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE);
ResetEvent(pDoc->m_hPostMsgEvent);//置为无信号
// 通知对话框
PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0);
continue;
}

dwMask = 0;
if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作,等待SetCommMask设定的事件出现
{
if(GetLastError() == ERROR_IO_PENDING)
{
// 无限等待重叠操作结果,如果EV_RXCHAR事件发生(串口收到字符并放入输入缓冲区中)
// 那么函数就结束等待。
GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE);
}
else
{
CloseHandle(os.hEvent);
return (UINT)-1;
}
}

}
CloseHandle(os.hEvent);

pDoc->ReceiveThread = false;

return 0; // 线程正常结束
}


// 工作者线程,负责发送数据
UINT CommProcT(LPVOID pParam)
{

DWORD FileLength;
DWORD Remainder; // 余数
DWORD Size; // 进程条每一格的字符数
DWORD j = 0;
BOOL fState;
DWORD length,dwLength = 1; // 成功写入缓冲区的字符数
COMSTAT ComStat;
DWORD dwErrorFlags;
/*
HWND hwnd;
CNcfileCtrlDlg dlg;
hwnd=dlg.GetSafeHwnd();
CNcfileCtrlDlg *pDoc=(CNcfileCtrlDlg *)GetWindow(hwnd,GW_OWNER);
*/
CNcfileCtrlDlg *pDoc = (CNcfileCtrlDlg*)pParam;
FileLength = pDoc->m_sNcFile.GetLength();

Remainder = FileLength%20; // 进程条范围从0到20
Size = (FileLength-Remainder)/20;

for(DWORD i=0; i<FileLength; i++)
{
char m_cChar;
if(i%Size == 0) // 显示进度
{
pDoc->m_cProgress.SetPos(j);
j++;
}
if(i == (FileLength-1))
pDoc->m_cProgress.SetPos(20);

if(WaitForSingleObject(pDoc->m_hKillThreadT,0)==WAIT_OBJECT_0) //终止线程事件有信号
{
pDoc->GetDlgItem(IDC_STOPT)->EnableWindow(FALSE);
pDoc->GetDlgItem(IDC_RECEIVE)->EnableWindow(TRUE);
pDoc->GetDlgItem(IDC_SENDING)->EnableWindow(TRUE);
pDoc->BeginThread=false;
//终止监视通信事件线程
TerminateThread(pDoc->m_pThreadEvent->m_hThread,0);
pDoc->EventThread=false;
AfxEndThread(0); //退出线程
}

if(pDoc->m_bXon)
WaitForSingleObject(pDoc->m_hXonEvent,INFINITE);
if(pDoc->m_bRts)
WaitForSingleObject(pDoc->m_hRtsEvent,INFINITE);
if(pDoc->m_bDsr)
WaitForSingleObject(pDoc->m_hDtrEvent,INFINITE);

m_cChar = pDoc->m_sNcFile.GetAt(i);
ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
fState = WriteFile(pDoc->m_hCom,&m_cChar,dwLength,&length,&pDoc->m_osWrite);
if(!fState){
if(GetLastError() == ERROR_IO_PENDING) //写操作被挂起
{
if(!GetOverlappedResult(pDoc->m_hCom,&pDoc->m_osWrite,&length,TRUE)) //写操作没有成功完成
{
::MessageBox(NULL,"发送代码出现错误!","错误",
MB_ICONERROR | MB_OK);
}
}
else
length=0;
}

if(!length)
{
::MessageBox(NULL,"发送代码出现错误,可能机床没准备好!","错误",
MB_ICONERROR | MB_OK);
pDoc->GetDlgItem(IDC_SENDING)->EnableWindow(TRUE);
pDoc->GetDlgItem(IDC_RECEIVE)->EnableWindow(TRUE);
pDoc->GetDlgItem(IDC_STOPT)->EnableWindow(FALSE);
pDoc->GetDlgItem(IDC_STOPING)->EnableWindow(FALSE);

// return (UINT)-1;
pDoc->BeginThread = false;
TerminateThread(pDoc->m_pThreadEvent->m_hThread,0);
pDoc->EventThread = false;
AfxEndThread(0); //退出线程
}
}
pDoc->GetDlgItem(IDC_SENDING)->EnableWindow(TRUE);
pDoc->GetDlgItem(IDC_RECEIVE)->EnableWindow(TRUE);
pDoc->GetDlgItem(IDC_STOPT)->EnableWindow(FALSE);
pDoc->GetDlgItem(IDC_STOPING)->EnableWindow(FALSE);

pDoc->BeginThread = false;
//终止监视通信事件线程
TerminateThread(pDoc->m_pThreadEvent->m_hThread,0);
pDoc->EventThread = false;

if(::MessageBox(NULL,"发送完毕!","提示", MB_ICONINFORMATION | MB_OK) == IDOK)//;
{
pDoc->m_cProgress.SetPos(0);
}
/* if(AfxMessageBox("发送完毕!",MB_OKCANCEL) == IDOK)
{


int m_iNumber;
int m_iLine;
LPSTR buf;
CString m_sTemp1;
buf = m_sTemp1.GetBuffer(2048);
m_iLine = pDoc->m_cNcFile.GetLineCount();
m_iNumber = pDoc->m_cNcFile.GetLine(m_iLine,buf,2048);
buf[m_iNumber] = '\0';
m_sTemp1.ReleaseBuffer();
pDoc->m_sEnd = buf;
pDoc->UpdateData(false);
}*/

return 0; //线程正常结束

}


// 工作者线程,负责监测通信事件
UINT CommProcEvent(LPVOID pParam)
{
DWORD dwCommEvent = 0,dwTrans,dwModemStatus;
DWORD dwStoredFlags;
OVERLAPPED osStatus = {0};
char buf;
BOOL fCTS,fDSR;
DWORD length = 1;

CNcfileCtrlDlg *pDoc = (CNcfileCtrlDlg*)pParam;
dwStoredFlags = EV_CTS | EV_DSR | EV_RXCHAR;

// 设置事件掩码
SetCommMask(pDoc->m_hCom,0);
if(!SetCommMask(pDoc->m_hCom,dwStoredFlags))
{
pDoc->EventThread = false;
return 0;
}

// 为重叠osStatus创建事件对象,手工重置,初始化为无信号的
osStatus.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(osStatus.hEvent == NULL)
{
return 0;
pDoc->EventThread = false;
}

if(!GetCommModemStatus(pDoc->m_hCom,&dwModemStatus))
{
::MessageBox(NULL,"不能获得针脚电压状态!","警告", MB_ICONWARNING | MB_OK);
pDoc->EventThread = false;
return 0;
}
else
{
// RTS/CTS流控协议
fCTS = MS_CTS_ON &dwModemStatus;
if(fCTS)
SetEvent(pDoc->m_hRtsEvent); // 置为有信号,可以发送;
else
ResetEvent(pDoc->m_hRtsEvent); // 置为无信号,不能发送;

// DTR/DSR流控协议
fDSR = MS_DSR_ON & dwModemStatus;
if(fDSR)
SetEvent(pDoc->m_hDtrEvent); // 置为有信号,可以发送
else
ResetEvent(pDoc->m_hDtrEvent); // 置为无信号,不能发送
}

while(pDoc->m_bConnected)
{
if(!WaitCommEvent(pDoc->m_hCom, &dwCommEvent, &osStatus)) // 重叠操作,等待SetCommMask设定的事件出现
{
if(GetLastError() == ERROR_IO_PENDING)
{
// 无限等待重叠操作结果,如果设定的事件发生,那么函数就结束等待。
GetOverlappedResult(pDoc->m_hCom, &osStatus, &dwTrans, TRUE);
}
// XON/XOFF协议
if ( ( dwCommEvent & EV_RXCHAR ) == EV_RXCHAR )
{
ReadFile(pDoc->m_hCom,&buf,length,&length,&pDoc->m_osRead);
if(buf == XOFF)
ResetEvent(pDoc->m_hXonEvent); // 置为无信号,不能发送;
if(buf == XON)
SetEvent(pDoc->m_hXonEvent); // 置为有信号,可以发送;
}
// RTS/CTS协议
if ( ( dwCommEvent & EV_CTS ) == EV_CTS )
{
if(!GetCommModemStatus(pDoc->m_hCom,&dwModemStatus))
{
::MessageBox(NULL,"不能获得针脚电压状态!","警告", MB_ICONWARNING | MB_OK);
pDoc->EventThread = false;
return 0;
}
else
{
fCTS = MS_CTS_ON &dwModemStatus;
if(fCTS)
SetEvent(pDoc->m_hRtsEvent); // 置为有信号,可以发送;
else
ResetEvent(pDoc->m_hRtsEvent); // 置为无信号,不能发送;
}
}
// DTR/DSR协议
if ( ( dwCommEvent & EV_DSR ) == EV_DSR )
{
if(!GetCommModemStatus(pDoc->m_hCom,&dwModemStatus))
{
::MessageBox(NULL,"不能获得针脚电压状态!","警告", MB_ICONWARNING | MB_OK);
pDoc->EventThread = false;
return 0;
}
else
{
fDSR = MS_DSR_ON & dwModemStatus;
if(fDSR)
SetEvent(pDoc->m_hDtrEvent); // 置为有信号,可以发送
else
ResetEvent(pDoc->m_hDtrEvent); // 置为无信号,不能发送
}
}
}
}

//////////////////////////////////////////////////////////////////////
// 测试代码
// CNcfileCtrlDlg *pDoc=(CNcfileCtrlDlg*)pParam;
// while(pDoc->m_bConnected)
// {
// WaitForSingleObject(pDoc->m_hRtsEvent,10000);
// SetEvent(pDoc->m_hXonEvent);
// }
///////////////////////////////////////////////////////////////////////
pDoc->Eve
cegaryli 2002-11-29
  • 打赏
  • 举报
回复
不能用两个串口或两台机器,启动自己的程序,监视一个已经被打开串口的收、发数据。大家可以下载一个PortMon程序,体验一下。如果用到设备驱动一级,那肯定与操作系统有关。roaringwind(www.gjwtech.com)能说的具体点吗?
sbw 2002-11-28
  • 打赏
  • 举报
回复
Saimen(单身情人) 虽不是一台机,但是这也是一种方法呀。
HuWenjin 2002-11-28
  • 打赏
  • 举报
回复
sbw(清风一笑) CAO 这也行? 不是一台机了
sbw 2002-11-28
  • 打赏
  • 举报
回复
俺来提供一个另类的方法:

需要多加一台计算机,这台机子有两个串口,把要监视的串口数据线先连到此机串口1上,再用一条数据线通过数据线把串口2连到目标机上,把传过来的信息再发送出去不就起到监视的作用了么?呵呵.

roaringwind 2002-11-28
  • 打赏
  • 举报
回复
需要用到虚拟驱动,且在不同的操作系统下不一样
sbw 2002-11-28
  • 打赏
  • 举报
回复
还是楼上的高明!
Phourm 2002-11-28
  • 打赏
  • 举报
回复
一台机上多安装几个串口不就OK
lhynew 2002-11-28
  • 打赏
  • 举报
回复
关注:楼主有没有进展?
HuWenjin 2002-11-28
  • 打赏
  • 举报
回复
接着笑吧,现在讨论一台机中
HuWenjin 2002-11-27
  • 打赏
  • 举报
回复
别人已打开了的?


关注 +
lhynew 2002-11-27
  • 打赏
  • 举报
回复
PortMon用的可能是替换设备驱动程序的方法。
加载更多回复(5)
今天小编要给大家介绍一款专业好用的串口通信桌面监控程序软件——串口监视工具。软件可以侦测、拦截、逆向分析串口通信协议,监视电脑串口活动,显示波特率和状态,并能保存日志记录,让您对应用程序操作串行端口的过程和细节,让您及时的模拟被侦听程序或设备的数据、控制流,提高工作效率。串口监视工具使用方便,速度快,质量高,对于用户来说是一款很不错的软件,小编这里推荐大家使用这款软件! 串口监视工具功能 串口调试: 和多数串口调试工具一样具有串口的收发功能. 本身特点: 自动检测串口(包括各种虚拟串口). 参数设置详细,能发送16进制,各种文件数据. 显示串口握手线信号, 显示各种硬件错误. 作用: 调试串口应用程序. 串口测试: 发送,接收大量伪随机码对串口设备/串口线路的质量进行测试. 能自动同步,可以测试单向的线路质量,代替昂贵的测试仪表. 随机码包括标准的 2^15-1,2^11-1,2^9-1和16bit人工码.自动/手动插入误码(1/10000,1/1000,单个). 自动记录各种测试结果. 作用: 测试串口设备/串口线路(测试时不要选软件流控). 串口监视: 不占用串口资源,监视串口通信的整个流程---从打开到关闭 监视串口的各种参数设置: 波特率,数据位,校验位,停止位,握手方式,超时数值,串口事件等等. 监视串口的收发数据,各种硬件信号,硬件错误. 作用: 监视程序对串口的访问流程. 串口过滤: 不占用串口资源,对流经串口的数据进行过滤. 在发送/接收数据流中改变字符. 在发送/接收数据流中进行字符代替. 在发送/接收数据流中删除字符. 作用: 模拟数据传输中出现的各种误码,丢失字符,调试串口的通信协议. 串口监视工具截图

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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