public bool SendData(int nChannelID, int nMainID, int nSubID, int nHandleCode, byte[] bytes) { IPC_Head_t head = new IPC_Head_t(); head.wMainCmdID = (UInt32)nMainID; head.wSubCmdID = (UInt32)nSubID; head.wHandleCode = (UInt32)nHandleCode; head.wDataSize = IPC_HEADER_LEN; if (bytes != null) { UInt32 tempDataBufferSize = (UInt32)bytes.Length; head.wDataSize += tempDataBufferSize; } ByteBuffer buffer = ByteBufferPool.PopPacket(); byte[] headBuffer = GameConvert.StructToByteArray <IPC_Head_t> (head); buffer.Position = 0; buffer.PushByteArray(headBuffer); if (bytes != null) { buffer.PushByteArray(bytes); } DATA_BUFFER sendData = new DATA_BUFFER(); sendData.buf = buffer.ToByteArray(); sendData.len = (UInt32)buffer.Length; mSendBufferQueue.Enqueue(new Send_Buffer(sendData, nChannelID)); ByteBufferPool.DropPacket(buffer); //LogUtil.Log ("IPC push messge |chan:"+nChannelID+"|main:"+nMainID+"|sub:"+nSubID+"|len:"+sendData.len); return(true); }
public void ReceiveLoop() { if (mIPCBase != IntPtr.Zero) { return; } /*important!!!! * win32窗口消息队列为线程单独所有,要开线程读取,则必须在该线程创建 */ IpcWindowHandle = CreateIpcModuleEx(ref mIPCBase, ref mIPCModule); if (IpcWindowHandle == IntPtr.Zero) { Logger.Sys.LogError("call CreateIpcModuleEx failed"); return; } Logger.Sys.Log("call CreateIpcModuleEx finished, handle:" + IpcWindowHandle.ToString("X")); mInitEvent.Set(); int channel = -1; DATA_BUFFER ipcData = new DATA_BUFFER(); while (mReceiveThreadRuning) { //缓存发送,必须push到创建线程发送,这里先发送还是先接收或者一次性全发完再接收待优化 if (mSendBufferQueue.Count != 0) { IntPtr ptr = IntPtr.Zero; Send_Buffer sendData = mSendBufferQueue.Dequeue(); try { ptr = Marshal.AllocHGlobal((int)sendData.Data.len); Marshal.Copy(sendData.Data.buf, 0, ptr, (int)sendData.Data.len); SendIpcData(mIPCBase, sendData.Channel, ptr, sendData.Data.len); //LogUtil.Log ("IPC send messge |chan:"+sendData.Channel+"|len:"+sendData.Data.len); } catch (Exception e) { Logger.Sys.LogError("send data to ipc failed|msg:" + e.Message + "|source:" + e.Source + "|chan:" + sendData.Channel + "|len:" + sendData.Data.len + "|stack:" + e.StackTrace ); } finally { Marshal.FreeHGlobal(ptr); } } try { if (PeekIPCMessage(mIPCBase, ref ipcData, ref channel) != true) { Thread.Sleep(10); continue; } ByteBuffer buffer = ByteBufferPool.PopPacket(ipcData.buf, (int)ipcData.len); IPC_Head_t head = GameConvert.ByteToStruct <IPC_Head_t>(buffer.PopByteArray(IPC_HEADER_LEN)); byte[] bytes = null; if (head.wDataSize > IPC_HEADER_LEN) { bytes = buffer.PopByteArray((int)head.wDataSize - IPC_HEADER_LEN); } ByteBufferPool.DropPacket(buffer); UInt32 mainID = head.wMainCmdID; UInt32 subID = head.wSubCmdID; UInt32 code = head.wHandleCode; if (mainID == IPC_MAIN_IPC_KERNEL) { //IPC控制协议 switch (subID) { case IPC_SUB_IPC_CLIENT_CONNECT: { SendData(channel, IPC_MAIN_IPC_KERNEL, IPC_SUB_IPC_SERVER_ACCEPT, 0, null); //接受连接 OnConnect(channel); break; } case IPC_SUB_IPC_SERVER_ACCEPT: { OnConnect(channel); break; } case IPC_SUB_IPC_CLIENT_CLOSE: { OnClose(channel); ResetChannel(channel); break; } default: { //break到OnRead处理 break; } } } OnRead(channel, (int)mainID, (int)subID, (int)code, bytes); } catch (Exception e) { Logger.Sys.LogError("peek msg|msg:" + e.Message + "|source:" + e.Source + "|stack:" + e.StackTrace ); } } //貌似c#线程会被野蛮退出,走不到这里执行 DestroyIpcModuleEx(mIPCBase); IpcWindowHandle = IntPtr.Zero; mIPCBase = IntPtr.Zero; mIPCModule = IntPtr.Zero; }