/// <exception cref="ArgumentOutOfRangeException">The completionStatuses item must have a valid OperationType.</exception> private void Loop() { var completionStatuses = new CompletionStatus[CompletionStatusArraySize]; while (!m_stopping) { // Execute any due timers. int timeout = ExecuteTimers(); int removed; if (!m_completionPort.GetMultipleQueuedCompletionStatus(timeout != 0 ? timeout : -1, completionStatuses, out removed)) { continue; } for (int i = 0; i < removed; i++) { if (completionStatuses[i].OperationType == OperationType.Signal) { var mailbox = (IOThreadMailbox)completionStatuses[i].State; mailbox.RaiseEvent(); } // if the state is null we just ignore the completion status else if (completionStatuses[i].State != null) { var item = (Item)completionStatuses[i].State; if (!item.Cancelled) { try { switch (completionStatuses[i].OperationType) { case OperationType.Accept: case OperationType.Receive: item.ProactorEvents.InCompleted( completionStatuses[i].SocketError, completionStatuses[i].BytesTransferred); break; case OperationType.Connect: case OperationType.Disconnect: case OperationType.Send: item.ProactorEvents.OutCompleted( completionStatuses[i].SocketError, completionStatuses[i].BytesTransferred); break; default: throw new ArgumentOutOfRangeException(); } } catch (TerminatingException) {} } } } } }
static void Main(string[] args) { ForceDotNet.Force(); CompletionPort completionPort = CompletionPort.Create(); AutoResetEvent listenerEvent = new AutoResetEvent(false); AutoResetEvent clientEvent = new AutoResetEvent(false); AutoResetEvent serverEvent = new AutoResetEvent(false); AsyncSocket listener = AsyncSocket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); completionPort.AssociateSocket(listener, listenerEvent); AsyncSocket server = AsyncSocket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); completionPort.AssociateSocket(server, serverEvent); AsyncSocket client = AsyncSocket.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); completionPort.AssociateSocket(client, clientEvent); Task.Factory.StartNew(() => { CompletionStatus [] completionStatuses = new CompletionStatus[10]; int removed; while (true) { var result = completionPort.GetMultipleQueuedCompletionStatus(-1, completionStatuses, out removed); for (int i = 0; i < removed; i++) { var completionStatus = completionStatuses[i]; Console.WriteLine("{0} {1} {2}", completionStatus.SocketError, completionStatus.OperationType, completionStatus.BytesTransferred); if (completionStatus.State != null) { AutoResetEvent resetEvent = (AutoResetEvent)completionStatus.State; resetEvent.Set(); } } Console.WriteLine("Handled {0} statuses", removed); Thread.Sleep(100); } }); listener.Bind(IPAddress.Any, 5555); listener.Listen(1); //Console.WriteLine(listener.LocalEndPoint); client.Bind(IPAddress.Any, 0); client.Connect("localhost", 5555); ////Thread.Sleep(100); listener.Accept(server); listenerEvent.WaitOne(); clientEvent.WaitOne(); byte[] sendBuffer = new byte[1] { 2 }; byte[] recvBuffer = new byte[1]; server.Receive(recvBuffer); client.Send(sendBuffer); clientEvent.WaitOne(); serverEvent.WaitOne(); ////Console.WriteLine("server received"); Console.ReadLine(); }
public void SendReceive() { CompletionPort completionPort = CompletionPort.Create(); bool exception = false; var task = Task.Factory.StartNew(() => { bool cancel = false; while (!cancel) { CompletionStatus [] completionStatuses = new CompletionStatus[10]; int removed; completionPort.GetMultipleQueuedCompletionStatus(-1, completionStatuses, out removed); for (int i = 0; i < removed; i++) { if (completionStatuses[i].OperationType == OperationType.Signal) { cancel = true; } else if (completionStatuses[i].SocketError == SocketError.Success) { EventWaitHandle manualResetEvent = (EventWaitHandle)completionStatuses[i].State; manualResetEvent.Set(); } else { exception = true; } } } }); AutoResetEvent clientEvent = new AutoResetEvent(false); AutoResetEvent acceptedEvent = new AutoResetEvent(false); AsyncSocket listener = AsyncSocket.CreateIPv4Tcp(); completionPort.AssociateSocket(listener, acceptedEvent); listener.Bind(IPAddress.Any, 0); int port = listener.LocalEndPoint.Port; listener.Listen(1); listener.Accept(); AsyncSocket clientSocket = AsyncSocket.CreateIPv4Tcp(); completionPort.AssociateSocket(clientSocket, clientEvent); clientSocket.Bind(IPAddress.Any, 0); clientSocket.Connect("localhost", port); clientEvent.WaitOne(); acceptedEvent.WaitOne(); var serverSocket = listener.GetAcceptedSocket(); AutoResetEvent serverEvent = new AutoResetEvent(false); completionPort.AssociateSocket(serverSocket, serverEvent); byte[] recv = new byte[1]; serverSocket.Receive(recv); byte[] data = new[] { (byte)1 }; clientSocket.Send(data); clientEvent.WaitOne(); // wait for data to be send serverEvent.WaitOne(); // wait for data to be received Assert.AreEqual(1, recv[0]); completionPort.Signal(null); task.Wait(); Assert.IsFalse(exception); completionPort.Dispose(); listener.Dispose(); serverSocket.Dispose(); clientSocket.Dispose(); }