能力值:
( LV2,RANK:10 )
2 楼
初步怀疑是内存访问互斥……但是还没有找到点……
能力值:
( LV2,RANK:10 )
3 楼
发现多线程编程思路还是有点混论,不过你定义了同步事件,貌似没有使用
func线程是在serverProc线程中启动,不知道是否有影响
能力值:
( LV2,RANK:10 )
4 楼
这么简单清晰的思路你还说混乱,我不知道能说什么。
能力值:
( LV2,RANK:10 )
5 楼
看雪的牛人呢?快现身啊
能力值:
( LV2,RANK:10 )
6 楼
这两天在看和这相关的,我觉得LPC服务端接收信息处应该只能有一个线程,NtListenPort和NtReplayReceivePort最终会在同一个ServerPort上等待消息,先等待的会阻塞后等待的,连接和请求都是一个消息,仅仅是Type不同,应在一个线程中接收这些消息。
能力值:
( LV2,RANK:10 )
7 楼
问题在于:
1.cpp 189行 ::Sleep(2000);
注释掉后应该正常。没有测试。大约看了下2个程序,应该是这里了
能力值:
( LV2,RANK:10 )
8 楼
如果没有这一句。。。服务线程会因为LPC线程listen而阻塞在监听的那一句……
通信不能成功
能力值:
( LV2,RANK:10 )
9 楼
简述下你的逻辑
Status = NtListenPort(hListenPort,&(ReceiveMessage.Header));
这句调用产生线程挂起等待客户连接。外围的do while 保证了循环监听。所以不存在需要Sleep的情况
HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,func,&ReceiveMessage,0,NULL);
工作线程,去处理连接,应该要完成Accept来接受并使用Complete唤醒 问题一:
如果没有Sleep那么fun线程得到的线程参数指针有可能被破坏,因为线程可能在执行时,调用者已经进入下一个do while循环,栈空间已被破坏。
问题二:
很有可能,你会产生某个Message无法收到的问题。在你解决了问题1后,他的表现是LPC_REQUEST时发送者无法接受返回的消息而陷入等待。
能力值:
( LV2,RANK:10 )
10 楼
即便你Sleep 2s也可能发生异常。而LZ原本的问题,应该是楼上的问题1,问题2的综合表现
能力值:
( LV2,RANK:10 )
11 楼
感谢你的解答
问题1:栈破坏的问题,这个问题我试过,我在堆上申请内存(不delete)然后传递到服务线程(func)也是不行的(不sleep),应该不是这个问题
问题2:表现是如果Server线程进入到NtListenPort函数之后,服务线程func会在
Status = NtReplyWaitReceivePort(hClinet,
(PVOID*)&a,
NULL,
&m_ReceiveMessage.Header
);
这一句挂起~
********************************************
原因猜测:
NtListenPort内部也是调用NtReplyWaitReceivePort的,所以可能跟这个有关
但是即使是同一个函数,他们等待的端口一个是hListen(监听端口),一个是hClinet(通信端口),怎么会卡住呢?
所以我猜测,hListen和hClinet虽然数值和含义都不同,但是可能两者是在同一个端口上等待,至于是哪一个我就搞不清楚了……
能力值:
( LV2,RANK:10 )
12 楼
最近比较忙,贴段我的代码
BOOLEAN CPort::ListenPort(
__in HANDLE hPortHandle,
__in PPACKET PacketBuffer
)
{
NTSTATUS status;
PVOID PortContext = NULL;
status = m_pPoolObject->m_tSystemApis.NtReplyWaitReceivePortEx(
hPortHandle,
(PVOID *)&PortContext,
(PPORT_MESSAGE)NULL,
(PPORT_MESSAGE) PacketBuffer,
&m_tTimePreListen
);
if(status == STATUS_TIMEOUT) {
return FALSE;
}
if ( !NT_SUCCESS(status) ) {
return FALSE;
}
BOOLEAN CPort::MessageLoop(
__in HANDLE hPortHandle,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in PPACKET PacketBuffer
)
{
NTSTATUS status;
PVOID PortContext = NULL;
//if(IsFlagOn(m_pPortObject->Flags, PORT_STATUS_DELETE_PEDING)) {
// return TRUE;
//}
//if(ClientInfo->ServerMode.IsTerminatePeding) {
// return TRUE;
//}
status = m_pPoolObject->m_tSystemApis.NtReplyWaitReceivePortEx(
hPortHandle,
(PVOID *)&PortContext,
(PPORT_MESSAGE)NULL,
(PPORT_MESSAGE) PacketBuffer,
&m_tTimePreListen
);
if(status == STATUS_TIMEOUT) {
return FALSE;
}
if ( !NT_SUCCESS(status) ) {
return FALSE;
}
有空我编译下调试好在看看。
能力值:
( LV2,RANK:10 )
13 楼
这2个函数都是在do while中调用。
能力值:
( LV2,RANK:10 )
14 楼
hListen以及hClinet被唤醒后都要对LPC的各种类型做处理
所以。我每个等待后都处理:
[CODE]
__try
{
switch(PacketBuffer->Lpc.u2.s2.Type)
{
case LPC_CONNECTION_REQUEST:
// 处理链接请求
NewClientConnected(PacketBuffer,&PacketBuffer->Connect.Context);
break;
// 如果端口没有完全关闭,仅通讯端口关闭
case LPC_PORT_CLOSED:
// 对方端口句柄关闭
{
CloseClientConnection(PacketBuffer, PortContext, LPC_PORT_CLOSED);
return TRUE;
}
case LPC_CLIENT_DIED:
// 通讯过程被结束,客户端才有的消息
{
CloseClientConnection(PacketBuffer, PortContext, LPC_CLIENT_DIED);
break;
}
case LPC_DATAGRAM:
RecvMessage(PacketBuffer, PortContext, LPC_DATAGRAM);
break;
case LPC_REQUEST:
RecvRequest(PacketBuffer, PortContext);
break;
default:
//
// We received a message type we didn't expect, probably due to
// error. BUGBUG - write an event
//
m_pPoolObject->PrintInfo("Message Loop # Unknow.\n");
break;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
//KdPrint(( "[DSW] Unexpected exception on LPC port: %08X\n",GetExceptionCode()));
}
[CODE]