话说做了一个服务器端和一个客户端,服务器端线程和客户端如下:
连接没有问题,问题是读取一次之后服务器端就会卡在WaitForSingleObject那里不动了,一定要重新断开再连接管道才会有信号,
看了下MSDN上面的例程也是重连的...
我的问题是能不能设置EVENT什么的不要再次连接呢??各位大侠帮忙看下...我快死了...// 管道线程
UINT CVCPipeServer::PipeServerThread(LPVOID Ptr)
{
CVCPipeServer* psvr = (CVCPipeServer*)Ptr;
if(!psvr)
{
AfxMessageBox(L"获取管道指针失败!");
return -1;
}
HANDLE SvrHandle = psvr->m_SvrHandle;
while(psvr->m_ThreadState)
{
if(WAIT_FAILED==WaitForSingleObject(psvr->m_hEvent,INFINITE))
{
TRACE0("等待对象失败!");
TRACE1("====CREATE PIPE ERROR:%d\n",GetLastError());
CloseHandle(psvr->m_hEvent);
CloseHandle(SvrHandle);
SvrHandle=NULL;
return -1;
}
//读取数据
char* buf = psvr->ReadPipe();
if(!buf)
continue;
//CString str(buf);//读取
if(psvr->m_pFrame)
::SendMessageA(psvr->m_pFrame->GetSafeHwnd(),ID_MESSAGE_FORM_CLIENT,(WPARAM)buf,0);
psvr->DisconnectAndReconnect();//一定要这个才行么?
//SetEvent(psvr->m_hEvent);
//SetEvent(SvrHandle);
}
return 0;
}
客户端是这样滴
CPipeClient::CPipeClient(void)
{
m_SvrHandle=NULL;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
if(!WaitNamedPipe(lpszPipename,2000))
{
//CString err;
//err.Format(_T("WaitNamedPipe失败 错误号:%d"),GetLastError());
TRACE1("WaitNamedPipe失败 错误号:%d",GetLastError());
//AfxMessageBox(err);
return;
}
m_SvrHandle=CreateFile(lpszPipename,GENERIC_READ | GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD dwMode = PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT;
if (INVALID_HANDLE_VALUE==m_SvrHandle)
{
CString err;
err.Format(_T("不能打开命名管道实例 错误号:%d"),GetLastError());
AfxMessageBox(err);
m_SvrHandle=NULL;
return;
} // Exit if an error other than ERROR_PIPE_BUSY occurs.
/*
BOOL fSuccess = SetNamedPipeHandleState(
m_SvrHandle, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if (!fSuccess)
{
CString err;
err.Format(_T("SetNamedPipeHandleState failed 错误号:%d"),GetLastError());
AfxMessageBox(err);
m_SvrHandle=NULL;
return;
}*/}
CPipeClient::~CPipeClient(void)
{
if(m_SvrHandle)
CloseHandle(m_SvrHandle);
}
// 读取管道内容
char* CPipeClient::ReadPipe(void)
{
DWORD dwRead;
if(m_SvrHandle==NULL)
return NULL;
memset(m_buf,0,1024);
if(!ReadFile(m_SvrHandle,m_buf,1024,&dwRead,NULL))
return NULL;
return m_buf;
}
// 写入管道
int CPipeClient::WritePipe(LPCTSTR param)
{
if(m_SvrHandle==NULL)
return -1;
memset(m_buf,0,1024);
wcstombs(m_buf, param, 1024 );
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(OVERLAPPED));
DWORD dwWrite;
if(!WriteFile(m_SvrHandle,m_buf,strlen(m_buf)+1,&dwWrite,&ovlap))
{
CString err;
err.Format(_T("写入数据失败 错误号:%d"),GetLastError());
AfxMessageBox(err);
return -1;
}
return 0;
}
连接没有问题,问题是读取一次之后服务器端就会卡在WaitForSingleObject那里不动了,一定要重新断开再连接管道才会有信号,
看了下MSDN上面的例程也是重连的...
我的问题是能不能设置EVENT什么的不要再次连接呢??各位大侠帮忙看下...我快死了...// 管道线程
UINT CVCPipeServer::PipeServerThread(LPVOID Ptr)
{
CVCPipeServer* psvr = (CVCPipeServer*)Ptr;
if(!psvr)
{
AfxMessageBox(L"获取管道指针失败!");
return -1;
}
HANDLE SvrHandle = psvr->m_SvrHandle;
while(psvr->m_ThreadState)
{
if(WAIT_FAILED==WaitForSingleObject(psvr->m_hEvent,INFINITE))
{
TRACE0("等待对象失败!");
TRACE1("====CREATE PIPE ERROR:%d\n",GetLastError());
CloseHandle(psvr->m_hEvent);
CloseHandle(SvrHandle);
SvrHandle=NULL;
return -1;
}
//读取数据
char* buf = psvr->ReadPipe();
if(!buf)
continue;
//CString str(buf);//读取
if(psvr->m_pFrame)
::SendMessageA(psvr->m_pFrame->GetSafeHwnd(),ID_MESSAGE_FORM_CLIENT,(WPARAM)buf,0);
psvr->DisconnectAndReconnect();//一定要这个才行么?
//SetEvent(psvr->m_hEvent);
//SetEvent(SvrHandle);
}
return 0;
}
客户端是这样滴
CPipeClient::CPipeClient(void)
{
m_SvrHandle=NULL;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
if(!WaitNamedPipe(lpszPipename,2000))
{
//CString err;
//err.Format(_T("WaitNamedPipe失败 错误号:%d"),GetLastError());
TRACE1("WaitNamedPipe失败 错误号:%d",GetLastError());
//AfxMessageBox(err);
return;
}
m_SvrHandle=CreateFile(lpszPipename,GENERIC_READ | GENERIC_WRITE,
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
DWORD dwMode = PIPE_TYPE_MESSAGE | // message-type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT;
if (INVALID_HANDLE_VALUE==m_SvrHandle)
{
CString err;
err.Format(_T("不能打开命名管道实例 错误号:%d"),GetLastError());
AfxMessageBox(err);
m_SvrHandle=NULL;
return;
} // Exit if an error other than ERROR_PIPE_BUSY occurs.
/*
BOOL fSuccess = SetNamedPipeHandleState(
m_SvrHandle, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if (!fSuccess)
{
CString err;
err.Format(_T("SetNamedPipeHandleState failed 错误号:%d"),GetLastError());
AfxMessageBox(err);
m_SvrHandle=NULL;
return;
}*/}
CPipeClient::~CPipeClient(void)
{
if(m_SvrHandle)
CloseHandle(m_SvrHandle);
}
// 读取管道内容
char* CPipeClient::ReadPipe(void)
{
DWORD dwRead;
if(m_SvrHandle==NULL)
return NULL;
memset(m_buf,0,1024);
if(!ReadFile(m_SvrHandle,m_buf,1024,&dwRead,NULL))
return NULL;
return m_buf;
}
// 写入管道
int CPipeClient::WritePipe(LPCTSTR param)
{
if(m_SvrHandle==NULL)
return -1;
memset(m_buf,0,1024);
wcstombs(m_buf, param, 1024 );
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(OVERLAPPED));
DWORD dwWrite;
if(!WriteFile(m_SvrHandle,m_buf,strlen(m_buf)+1,&dwWrite,&ovlap))
{
CString err;
err.Format(_T("写入数据失败 错误号:%d"),GetLastError());
AfxMessageBox(err);
return -1;
}
return 0;
}
解决方案 »
- ADO访问SQL sever数据库当前记录集不支持更新,这可能是程序提供的限制,也可能是选定锁定类型的限制。高分请大家帮忙解答。
- 文本编程——退格键
- 基于对话框的应用程序怎么才能使用CFileDialog
- 关于钩子,高手请进.
- 在c/s下如何实现两端互传结构类型的数据
- 关于vc串口通信的问题,急!
- 请问如何把原来的非MFC工程转换成MFC工程?
- 在对话框里面怎么在onbutton事件里面使原单文档视图指向另一个链接(视图是Chtmlview)?
- 请问大家如何现实应用程序退出的同时把应用程序删除
- 关于0.01的问题?请高手解决!
- vc++6.0与sql server2008
- VS2010中运行程序会出现下面问题
CreateEvent那里也设置过自动恢复信号,也没有用呀..