private void ReceiveData(IntPtr socket) { PerIoData perIoData = new PerIoData(); GCHandle gchPerIoData = GCHandle.Alloc(perIoData, GCHandleType.Pinned); Overlapped overlapped = new Overlapped(); overlapped.mGCHPerIoData = gchPerIoData; perIoData.mGCHOverlapped = GCHandle.Alloc(overlapped, GCHandleType.Pinned); byte[] buffer = new byte[BUF_SIZE]; perIoData.mGCHBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); perIoData.mWSABuffer.mLength = BUF_SIZE; perIoData.mWSABuffer.mPointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); perIoData.mType = OperationType.OT_RECEIVE; int recvByte = 0; SocketFlags socketFlags = SocketFlags.None; SocketError result = WSARecv(socket, ref perIoData.mWSABuffer, 1, out recvByte, ref socketFlags, perIoData.mGCHOverlapped.AddrOfPinnedObject(), IntPtr.Zero); if (result != SocketError.SocketError && result != SocketError.Success && result != SocketError.IOPending) { Console.WriteLine("WSARecv Error! : " + result.ToString() + WSAGetLastError()); } }
public void WorkerThread() { while (true) { IntPtr addressOfPerHandleData; IntPtr addressOfOverlapped; uint transferredBytes; // Get! bool result = GetQueuedCompletionStatus(mCompletionPort, out transferredBytes, out addressOfPerHandleData, out addressOfOverlapped, uint.MaxValue); if (result == false) { Console.WriteLine("GetQueuedCompletionStatus Error! : " + WSAGetLastError()); Thread.Sleep(1000); continue; } // Retrive data GCHandle gchPerHandleData = GCHandle.FromIntPtr(addressOfPerHandleData); PerHandleData perHandleData = (PerHandleData)gchPerHandleData.Target; Overlapped overlapped = new Overlapped(); Marshal.PtrToStructure(addressOfOverlapped, overlapped); PerIoData perIoData = (PerIoData)overlapped.mGCHPerIoData.Target; switch (perIoData.mType) { case OperationType.OT_DISCONNECT: break; case OperationType.OT_RECEIVE: Interlocked.Add(ref mTotalRecvBytes, transferredBytes); Console.WriteLine("ReceiveData Success! (Total bytes : " + mTotalRecvBytes + ")"); ReceiveData(perHandleData.mSocket); break; case OperationType.OT_SEND: break; } // Release perIoData perIoData.mGCHBuffer.Free(); perIoData.mGCHOverlapped.Free(); overlapped.mGCHPerIoData.Free(); // Disconnect (Release perHandleData) if (transferredBytes == 0) { perHandleData.mThis.Free(); } } }