示例#1
0
        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();
                }
            }
        }
示例#2
0
        public void Start()
        {
            // Initialize WS
            WSAData wsaData;

            if (WSAStartup(0x0202, out wsaData) != SocketError.Success)
            {
                Console.WriteLine("WSAStartup Error! : " + WSAGetLastError());
                return;
            }

            // Create completion port
            mCompletionPort = CreateIoCompletionPort(new IntPtr(-1), IntPtr.Zero, IntPtr.Zero, 0);
            if (mCompletionPort.IsInvalid)
            {
                Console.WriteLine("CreateIoCompletionPort Error! : " + WSAGetLastError());
                return;
            }

            // Create listen socket
            mListenSocket = WSASocket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, IntPtr.Zero, 0, SocketConstructorFlags.WSA_FLAG_OVERLAPPED);
            if (mListenSocket.ToInt32() == 0)
            {
                Console.WriteLine("WSASocket Error! : " + WSAGetLastError());
                return;
            }

            // Bind address
            IPEndPoint address         = new IPEndPoint(IPAddress.Any, 9001);
            FieldInfo  bufferFieldInfo = typeof(SocketAddress).GetField("m_Buffer", BindingFlags.Instance | BindingFlags.NonPublic);
            FieldInfo  sizeFieldInfo   = typeof(SocketAddress).GetField("m_Size", BindingFlags.Instance | BindingFlags.NonPublic);

            mMyAddress     = (byte[])bufferFieldInfo.GetValue(address.Serialize());
            mMyAddressSize = (int)sizeFieldInfo.GetValue(address.Serialize());

            if (bind(mListenSocket, mMyAddress, mMyAddressSize) != SocketError.Success)
            {
                Console.WriteLine("bind Error! : " + WSAGetLastError());
                return;
            }

            // Listen
            if (listen(mListenSocket, 128) != SocketError.Success)
            {
                Console.WriteLine("listen Error! : " + WSAGetLastError());
                return;
            }

            // Create worker thread and run
            CreateWorkerThread(WORKER_THREAD_COUNT);

            // Accept loop
            while (true)
            {
                // Accept (Wait...)
                IntPtr acceptedSocket;
                acceptedSocket = accept(mListenSocket, mMyAddress, ref mMyAddressSize);

                // Welcome!
                PerHandleData perHandleData    = new PerHandleData();
                GCHandle      gchPerHandleData = GCHandle.Alloc(perHandleData, GCHandleType.Pinned);
                perHandleData.mSocket = acceptedSocket;
                perHandleData.mThis   = gchPerHandleData;

                // Assign socket to completion port
                CreateIoCompletionPort(acceptedSocket, mCompletionPort.DangerousGetHandle(), GCHandle.ToIntPtr(gchPerHandleData), 0);

                // Change socket options

                /*
                 * Object socketRecvBufferSize = 0;
                 * int oldSocketRecvBufferSize = 0;
                 * getsockopt(acceptedSocket, SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, ref socketRecvBufferSize, ref oldSocketRecvBufferSize);
                 * ...
                 */

                // Receive
                ReceiveData(acceptedSocket);
            }
        }