首页
社区
课程
招聘
[求助]LPC只能双向通信吗?支持一对多吗?
发表于: 2012-1-13 17:56 9100

[求助]LPC只能双向通信吗?支持一对多吗?

2012-1-13 17:56
9100
参考:

http://bbs.pediy.com/showthread.php?p=1037993#post1037993
http://bbs.pediy.com/showthread.php?t=140154

简单模式下:

创建一个监听端口,然后监听,当客户端连接时,然后双方得到通信端口,从而可以同步或者异步的通讯。

这是一对一的通讯~

那么LPC支持一对多吗?我修改过上面两个连接的代码,发现不可行

LPC线程:监听发起线程
服务线程:与客户端通信的线程,由LPC线程创建
客户端线程:请求LPC服务的线程

LPC线程监听端口,当客户端连接时,LPC线程创建服务线程与客户端通信,此时通信完全没问题。那么在服务线程和客户端通信时,LPC线程再次进入监听函数时候,正在通信的客户端连接和服务线程就会挂起。

有没有让一个监听端口可以与多个客户端通信的方法?

不能让一个LPC线程通过创建线程与多个客户端通信的话,那么LPC的方式就比本地socket的方式差了不是一点半点……除了一个没有办法量化的速度外,几乎毫无优势……

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 67
活跃值: (91)
能力值: ( 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;
}
2012-1-13 22:48
0
雪    币: 2
活跃值: (164)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我估计LPC肯定是这样的,但是。。。

服务线程和客户端线程正在通信的时候。。。。

LPC线程只要再次调用NtListenPort,服务线程和客户端线程就挂起了,不能继续通信了……
2012-1-14 11:11
0
雪    币: 33
活跃值: (10)
能力值: ( 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); }
};

2012-1-14 22:13
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
在我的封装模型下
实测1024个客户端并发20万个报文请求,2273ms完成发送
服务端在接受时处理稍微慢了几百ms.
测试机器:
i7 930 OC4.0Ghz - 6GB内存
Xeon 5506 2.13G
两个平台浮动不大。

支持无限大小的报文,支持报文分包重组
2012-1-14 22:17
0
雪    币: 2
活跃值: (164)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
太复杂了……即使对着你这个头文件的思路去写,估计也要蛮久

感谢你的解答……

ps: 在cpu核心一定的情况下,1024个客户端并发不一定比2个并发数据量大……
2012-1-15 01:56
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
..每个客户端for循环发送10万个包。每个包的数据长度是MAX_PATH,也就是超过了256的LPC端口报文长度
所以需要20万个LPC消息。。。
2012-1-17 11:51
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
MAX_PATH是260吧。。。。。。
2012-2-15 08:38
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
请看 “超过”两字修饰。
另外补充下,x86是256,x64是512。仅仅举例下,别纠结这个了
2012-2-16 16:09
0
游客
登录 | 注册 方可回帖
返回
//