能力值:
( LV6,RANK:80 )
|
-
-
2 楼
你改的代码肯定有问题,你要知道,win32子系统用于通知csrss.exe的消息全是基于LPC的。
\\Windows\\ApiPort这个port对象。给你看看reactOS的部分代码 VOID
WINAPI
ClientConnectionThread(HANDLE ServerPort)
{
NTSTATUS Status;
BYTE RawRequest[LPC_MAX_DATA_LENGTH];
PCSR_API_MESSAGE Request = (PCSR_API_MESSAGE)RawRequest;
PCSR_API_MESSAGE Reply;
PCSRSS_PROCESS_DATA ProcessData;
PCSR_THREAD ServerThread;
DPRINT("CSR: %s called\n", __FUNCTION__);
/* Connect to user32 */
while (!CsrConnectToUser())
{
/* Keep trying until we get a response */
NtCurrentTeb()->Win32ClientInfo[0] = 0;
//NtDelayExecution(FALSE, &TimeOut);
}
/* Reply must be NULL at the first call to NtReplyWaitReceivePort */
ServerThread = NtCurrentTeb()->CsrClientThread;
Reply = NULL;
/* Loop and reply/wait for a new message */
for (;;)
{
/* Send the reply and wait for a new request */
Status = NtReplyWaitReceivePort(hApiPort,
0,
&Reply->Header,
&Request->Header);
/* Client died, continue */
if (Status == STATUS_INVALID_CID)
{
Reply = NULL;
continue;
}
if (!NT_SUCCESS(Status))
{
DPRINT1("NtReplyWaitReceivePort failed: %lx\n", Status);
break;
}
/* If the connection was closed, handle that */
if (Request->Header.u2.s2.Type == LPC_PORT_CLOSED)
{
DPRINT("Port died, oh well\n");
CsrFreeProcessData( Request->Header.ClientId.UniqueProcess );
break;
}
[COLOR="Red"] if (Request->Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
{
CsrpHandleConnectionRequest((PPORT_MESSAGE)Request, ServerPort);[/COLOR]
Reply = NULL;
continue;
}
if (Request->Header.u2.s2.Type == LPC_CLIENT_DIED)
{
DPRINT("Client died, oh well\n");
Reply = NULL;
continue;
}
if ((Request->Header.u2.s2.Type != LPC_ERROR_EVENT) &&
(Request->Header.u2.s2.Type != LPC_REQUEST))
{
DPRINT1("CSR: received message %d\n", Request->Header.u2.s2.Type);
Reply = NULL;
continue;
}
DPRINT("CSR: Got CSR API: %x [Message Origin: %x]\n",
Request->Type,
Request->Header.ClientId.UniqueThread);
/* Get the Process Data */
ProcessData = CsrGetProcessData(Request->Header.ClientId.UniqueProcess);
if (ProcessData == NULL)
{
DPRINT1("Message %d: Unable to find data for process 0x%x\n",
Request->Header.u2.s2.Type,
Request->Header.ClientId.UniqueProcess);
break;
}
if (ProcessData->Terminated)
{
DPRINT1("Message %d: process %d already terminated\n",
Request->Type, Request->Header.ClientId.UniqueProcess);
continue;
}
/* Check if we got a hard error */
if (Request->Header.u2.s2.Type == LPC_ERROR_EVENT)
{
/* Call the Handler */
CsrHandleHardError(ProcessData, (PHARDERROR_MSG)Request);
}
else
{
PCSR_THREAD Thread;
PCSRSS_PROCESS_DATA Process = NULL;
//DPRINT1("locate thread %lx/%lx\n", Request->Header.ClientId.UniqueProcess, Request->Header.ClientId.UniqueThread);
Thread = CsrLocateThreadByClientId(&Process, &Request->Header.ClientId);
//DPRINT1("Thread found: %p %p\n", Thread, Process);
/* Call the Handler */
if (Thread) NtCurrentTeb()->CsrClientThread = Thread;
CsrApiCallHandler(ProcessData, Request);
if (Thread) NtCurrentTeb()->CsrClientThread = ServerThread;
}
/* Send back the reply */
Reply = Request;
}
/* Close the port and exit the thread */
// NtClose(ServerPort);
DPRINT("CSR: %s done\n", __FUNCTION__);
RtlExitUserThread(STATUS_SUCCESS);
}
NTSTATUS WINAPI
CsrpHandleConnectionRequest (PPORT_MESSAGE Request,
IN HANDLE hApiListenPort)
{
NTSTATUS Status;
HANDLE ServerPort = NULL, ServerThread = NULL;
PCSRSS_PROCESS_DATA ProcessData = NULL;
REMOTE_PORT_VIEW LpcRead;
CLIENT_ID ClientId;
LpcRead.Length = sizeof(LpcRead);
ServerPort = NULL;
DPRINT("CSR: %s: Handling: %p\n", __FUNCTION__, Request);
Status = NtAcceptConnectPort(&ServerPort,
NULL,
Request,
TRUE,
0,
& LpcRead);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSR: NtAcceptConnectPort() failed\n");
return Status;
}
ProcessData = CsrGetProcessData(Request->ClientId.UniqueProcess);
if (ProcessData == NULL)
{
ProcessData = CsrCreateProcessData(Request->ClientId.UniqueProcess);
if (ProcessData == NULL)
{
DPRINT1("Unable to allocate or find data for process 0x%x\n",
Request->ClientId.UniqueProcess);
Status = STATUS_UNSUCCESSFUL;
return Status;
}
}
ProcessData->CsrSectionViewBase = LpcRead.ViewBase;
ProcessData->CsrSectionViewSize = LpcRead.ViewSize;
ProcessData->ServerCommunicationPort = ServerPort;
Status = NtCompleteConnectPort(ServerPort);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSR: NtCompleteConnectPort() failed\n");
return Status;
}
Status = RtlCreateUserThread(NtCurrentProcess(),
NULL,
TRUE,
0,
0,
0,
(PTHREAD_START_ROUTINE)ClientConnectionThread,
ServerPort,
& ServerThread,
&ClientId);
if (!NT_SUCCESS(Status))
{
DPRINT1("CSR: Unable to create server thread\n");
return Status;
}
CsrAddStaticServerThread(ServerThread, &ClientId, 0);
NtResumeThread(ServerThread, NULL);
NtClose(ServerThread);
Status = STATUS_SUCCESS;
DPRINT("CSR: %s done\n", __FUNCTION__);
return Status;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
我估计LPC肯定是这样的,但是。。。
服务线程和客户端线程正在通信的时候。。。。
LPC线程只要再次调用NtListenPort,服务线程和客户端线程就挂起了,不能继续通信了……
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
服务器可以对应多个客户端广播通讯。
LPC系统只是 简单提供接口,更多功能需要自己处理
class CPort
{
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
CPort 构造函数等.保存端口池对象
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
public:
CPort( PCPortPool PoolObject );
~CPort();
// 对于CPortPool来说建立友元关系
friend class CPortPool;
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
自定义 New 操作符
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
public:
PVOID operator new(size_t n) { return CServerAllocatePool( n ); }
VOID operator delete(PVOID p) { CServerFreePool(p); }
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
端口私有属性
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
private:
// 回指端口池
PCPortPool m_pPoolObject;
// 端口描述符
HPORT m_pPortObject;
// 守护线程
ULONG_PTR m_pClassThread;
// 线程事件, 客户端模式为监听的线程,服务器模式为链接线程
ULONG_PTR m_pThreadEvent;
private:
// 每次监听的超时时间
LARGE_INTEGER m_tTimePreListen;
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
端口描述符的引用计数管理
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
private:
LONG IncrementPort();
LONG DecrementPort();
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
内部处理接口函数
/*/////////////////////////////////////////////////////////////////////////////////////////////////////
private:
// 创建一个端口描述符
BOOLEAN Create(
__in PWCHAR strPortName,
__in PVOID SecurityDescriptor,
__in ULONG Flags,
__in ULONG MaxThreads,
__in PVOID PortContext,
__in BOOLEAN MustDoConnect,
__in BOOLEAN IsConnectClient
);
BOOLEAN InitializeConnectPort(
__in PWCHAR strPortName,
__in ULONG Flags,
__in ULONG MaxThreads,
__in PVOID PortContext,
__in BOOLEAN MustDoConnect
);
BOOLEAN InitializeServerPort(
__in PWCHAR strPortName,
__in PVOID SecurityDescriptor,
__in ULONG Flags,
__in ULONG MaxThreads,
__in PVOID PortContext
);
// 删除端口
BOOLEAN DeletePort(
__in VOID
);
BOOLEAN DeleteConnectPort(
__in VOID
);
BOOLEAN DeleteServerPort(
__in VOID
);
VOID DeleteClient(
__in PPORT_CLIENT_DESCRIPTOR ClientDescriptor,
__in BOOLEAN NotWait
);
VOID SendMultipleItems(
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in HANDLE hPortHandle
);
BOOLEAN SendSingleItem(
__in PPORT_SEND_ITEM SendItem,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in HANDLE hPortHandle
);
VOID CanceSend(
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in PLUID MessageId
);
VOID RecvMessage(
__in PPACKET PacketBuffer,
__in PVOID Context,
__in CSHORT MsgType
);
VOID RecvRequest(
__in PPACKET PacketBuffer,
__in PVOID Context
);
// 获取下个端口
PCPort Next();
// 获取下个快速端口
PCPort NextFastPort();
public:
// 异步发送队列
virtual VOID SendWorker(
__in PPORT_CLIENT_DESCRIPTOR ClientInfo
);
// 消息队列
virtual VOID MessageWorker(
__in PPORT_CLIENT_DESCRIPTOR ClientInfo
);
virtual VOID ThreadsDaemon(
__in PPORT_CLIENT_DESCRIPTOR ClientInfo
);
// 链接监听线程
virtual VOID ConnectAppect(
__in PVOID Paramter
);
private:
// 链接建立,死亡处理
BOOLEAN ListenPort(
__in HANDLE hPortHandle,
__in PPACKET PacketBuffer
);
BOOLEAN MessageLoop(
__in HANDLE hPortHandle,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in PPACKET PacketBuffer
);
// 新链接建立
VOID NewClientConnected(
__in PPACKET PacketBuffer,
__in PCONNECT_PAYLOAD ConnectCtx
);
// 链接将关闭
VOID CloseClientConnection(
__in PPACKET PacketBuffer,
__in PVOID Context,
__in CSHORT MsgType
);
// KEY初始化
VOID KeyInitialize(
__in PLUID RndKey,
__in PLUID Cookies,
__in ULONG Pid,
__in ULONG Tid
);
// 内存管理
private:
// 申请PORT结构体资源
BOOLEAN InitializePort(
__in VOID
);
// 释放资源
VOID UninitializePort(
__in VOID
);
private:
VOID CleanupMessageStack(
__in PPACKET_HEADER PacketHeader,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo
);
VOID CleanupPacketStackItems (
__in PPORT_MESSAGE_STACK MessageItem
);
VOID FreeMessageMemory(
__in PPACKET PacketBuffer
);
VOID RecvMessageStackHeader(
__in PPACKET PacketBuffer,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo
);
VOID RecvMessageStackFooter(
__in PPACKET PacketBuffer,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in PPORT_MESSAGE_STACK MessageItem
);
PPORT_MESSAGE_STACK CheckMessageStack(
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in PPACKET PacketBuffer
);
VOID RecvMessageData(
__in PPACKET PacketBuffer,
__in PPORT_CLIENT_DESCRIPTOR ClientInfo,
__in PPORT_MESSAGE_STACK MessageItem
);
public:
ULONG SendPort(
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in USHORT MessageType,
__in PVOID DataBuffer,
__in ULONG DataSize
);
BOOLEAN RequestPortEx(
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in USHORT MessageType,
__in PPORT_DATA_ENTRY DataEntries,
__in ULONG NumberOfDataEntries,
__inout_opt PVOID *ReplyPacketPtr
);
BOOLEAN ReplyPortEx(
__in PPACKET Packet,
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in PVOID ReplyBuffer,
__in ULONG ReplySize
);
VOID FreeReplyPacket(
__in PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in PVOID Packet
);
VOID FreeRemoteMemory(
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in PVOID Packet
);
BOOLEAN RequestPort(
__in_opt PPORT_CLIENT_DESCRIPTOR TargetInfo,
__in USHORT MessageType,
__in PVOID DataBuffer,
__in ULONG DataSize,
__inout_opt PVOID *ReplyPacketPtr
);
// 根据LUID查找客户端信息
PPORT_CLIENT_DESCRIPTOR FindClient(
__in PLUID ClientCookies
);
// 根据客户端名称查找客户端
public:
// 打开端口
BOOLEAN OpenPort(
__in VOID
);
// 关闭端口
BOOLEAN ClosePort(
__in VOID
);
// 挂起端口
ULONG SuspendPort(
__in VOID
);
// 恢复端口
ULONG ResumePort(
__in VOID
);
// 启动端口
VOID StartPort(
__in VOID
);
// 设置端口上下文
VOID SetContextPort(
__in PVOID Context
);
// 获取端口上下文
PVOID GetContextPort(
__in VOID
);
// 设置端口标志
ULONG SetPortFlags(
__in ULONG NewFlags
);
// 获取端口标志
ULONG GetPortFlags(
__in VOID
);
// 查询端口信息
BOOLEAN QueryInformationPort(
__in PORT_INFORMATION_CLASS PortInformationClass,
__in PVOID PortInfo,
__in ULONG InfoSize,
__out_opt PULONG BytesRequest
);
// 设置端口信息
BOOLEAN SetInformationPort(
__in PORT_INFORMATION_CLASS PortInformationClass,
__in PVOID PortInfo,
__in ULONG InfoSize
);
// 关联一个端口到本端口
VOID AttachMasterPort(
__in PCPort TargetPort
);
// 关联一个属性端口到本端口
VOID AttachFastPort(
__in PCPort TargetPort
);
// 从本端口取消关联一个端口
VOID DetachMasterPort(
__in PCPort TargetPort
);
// 取消一个属性端口的关联
VOID DetachFastPort(
__in PCPort TargetPort
);
// 移除本端口的头部关联位置
PCPort RemoveFast(
VOID
);
// 移除属性端口的头部关联位置
PCPort RemoveMaster(
VOID
);
};
class CPortPool
{
public:
CPortPool( USHORT MaxPorts = 1 ); // 构造函数
~CPortPool(); // 析构函数
private:
// 第一个被创建的Port
PCPort m_pPortHead;
// 第一个被创建的ClientPort
PCPort m_pClientPortHead;
// 第一个被创建的ServerPort;
PCPort m_pServerPortHead;
// 当前有多少个Ports
LONG m_nNumberOfPorts;
// 最大支持的端口数
LONG m_nMaxPorts;
// 挂起线程
PVOID m_pSuspendThread;
// 恢复线程
PVOID m_pResumeThread;
private:
//
// PORT结束的信号事件
// 初始化为有信号,在创建第一个端口时设置为无信号
// 在关闭最后一个端口时为有信号
//
ULONG_PTR m_pNoBody;
// 操作各个链表的资源锁
ULONG_PTR m_pResource;
private:
// 初始化Native API
virtual BOOLEAN InitializeApi();
public:
// 对NoBody进行检测,等待NOBODY为信号状态
virtual VOID WaitEvent( ULONG_PTR Event );
// 设置端口池正在运行
virtual VOID SetEvent( ULONG_PTR Event );
// 设置端口池已空载
virtual VOID ClearEvent( ULONG_PTR Event );
// 测试事件是否有信号
virtual BOOLEAN ReadEvent( ULONG_PTR Event );
public:
// 初始化端口池队列检测事件
virtual ULONG_PTR InitializeEvent( BOOLEAN AutoClear = TRUE );
// 反初始化...
virtual VOID UninitializeEvent( ULONG_PTR Event );
// 初始化端口池链表锁定
virtual ULONG_PTR InitializeResource();
// 反初始化端口池链表锁
virtual VOID UninitializeResource( ULONG_PTR Lock);
// 共享锁定对象
virtual VOID PushReadLock( ULONG_PTR Lock );
// 独占锁定
virtual VOID PushWriteLock( ULONG_PTR Lock );
// 解锁对象
virtual VOID PopLock( ULONG_PTR Lock );
public:
// 申请一段内存
virtual PVOID AllocatePool(
__in SIZE_T PoolSize
);
// 释放申请的内存
virtual VOID FreePool(
__in PVOID PoolBase
);
// 挂起线程
ULONG SuspendThread(
__in ULONG_PTR hThread
);
// 还原线程
ULONG ResumeThread(
__in ULONG_PTR hThread
);
// 设置线程优先级
VOID SetThreadLevel(
__in LONG Level
);
//运行时环境
BOOLEAN IsWow64System(
VOID
);
public:
// 创建线程
virtual HANDLE CreatePoolThread(
__in PVOID ThreadRoutine,
__in PVOID ThreadContext
);
//
// 转换句柄为对象 - 仅内核模式,用户模式为输入转输出返回
// 内核模式为创建对象,并且关闭句柄
//
virtual ULONG_PTR GetObject(
__in HANDLE hObjectHandle
);
virtual HANDLE GetHandle(
__in ULONG_PTR ObjectPtr
);
// 关闭句柄
virtual VOID CloseHandle(
__in HANDLE hObjectHandle
);
// 关闭对象 - 仅内核模式
virtual VOID CloseObject(
__in ULONG_PTR ObjectPtr
);
public:
// 创建GUID
virtual BOOLEAN CreateUuid(
__in GUID *Uid
);
// 创建LUID
virtual BOOLEAN CreateLocallyUniqueId(
__in PLUID Luid
);
public:
// 创建服务端口
PCPort CreatePort(
__in PVOID strPortName,
__in PVOID SecurityDescriptor,
__in ULONG Flags,
__in ULONG MaxThreads,
__in PVOID PortContext
);
// 连接到指定的端口
PCPort ConnectPort(
__in PVOID strPortName,
__in ULONG Flags,
__in ULONG MaxThreads,
__in PVOID PortContext,
__in BOOLEAN MustDoConnect
);
// 摧毁端口或将指定的端口标识为正在删除
BOOLEAN DestroyPort(
__in PCPort PortObject
);
public:
// 获取当前创建的端口数量
LONG GetNumberOfPort();
// 获取下一个端口
PCPort GetNextPort(
__in PCPort PortObject
);
// 获取下一个链接性质的端口
PCPort GetNextClient(
__in PCPort PortObject
);
// 获取下一个服务性质的端口
PCPort GetNextServer(
__in PCPort PortObject
);
public:
// 类对象实体初始化
BOOLEAN ServiceInitSystem();
// 类对象反初始化
VOID ServiceCloseSystem();
// 端口对象实际关闭的回调通知// 同步计数器等操作
VOID PortDeletedCall( PCPort PortObject );
public:
VOID PrintInfo(
char *Buffer
);
public:
// 系统基本信息
SYSTEM_BASIC_INFORMATION m_tSystemBasicInfo;
// 系统API表
SYSTEM_LPCAPI m_tSystemApis;
// 是否在WOW64模式下
BOOLEAN m_bIsSystemWow64;
public:
PVOID operator new(size_t n) { return CServerAllocatePool( n ); }
VOID operator delete(PVOID p) { CServerFreePool(p); }
};
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
在我的封装模型下
实测1024个客户端并发20万个报文请求,2273ms完成发送
服务端在接受时处理稍微慢了几百ms.
测试机器:
i7 930 OC4.0Ghz - 6GB内存
Xeon 5506 2.13G
两个平台浮动不大。
支持无限大小的报文,支持报文分包重组
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
太复杂了……即使对着你这个头文件的思路去写,估计也要蛮久
感谢你的解答……
ps: 在cpu核心一定的情况下,1024个客户端并发不一定比2个并发数据量大……
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
..每个客户端for循环发送10万个包。每个包的数据长度是MAX_PATH,也就是超过了256的LPC端口报文长度
所以需要20万个LPC消息。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
MAX_PATH是260吧。。。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
请看 “超过”两字修饰。
另外补充下,x86是256,x64是512。仅仅举例下,别纠结这个了
|