1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Net.Test.Common; 6 7 namespace System.Net.Sockets.Tests 8 { 9 // Provides a dummy _socket server that accepts connections and echoes data sent 10 public class SocketTestServerAPM : SocketTestServer 11 { 12 private VerboseTestLogging _log; 13 14 private Socket _socket; 15 private int _receiveBufferSize; 16 private volatile bool _disposed = false; 17 18 protected sealed override int Port { get { return ((IPEndPoint)_socket.LocalEndPoint).Port; } } 19 public sealed override EndPoint EndPoint { get { return _socket.LocalEndPoint; } } 20 SocketTestServerAPM(int numConnections, int receiveBufferSize, EndPoint localEndPoint)21 public SocketTestServerAPM(int numConnections, int receiveBufferSize, EndPoint localEndPoint) 22 { 23 _log = VerboseTestLogging.GetInstance(); 24 _receiveBufferSize = receiveBufferSize; 25 26 _socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 27 _socket.Bind(localEndPoint); 28 _socket.Listen(numConnections); 29 30 _socket.BeginAccept(OnAccept, null); 31 } 32 Dispose(bool disposing)33 protected override void Dispose(bool disposing) 34 { 35 if (disposing) 36 { 37 _socket.Dispose(); 38 _disposed = true; 39 } 40 } 41 OnAccept(IAsyncResult result)42 private void OnAccept(IAsyncResult result) 43 { 44 Socket client = null; 45 46 if (_disposed) 47 { 48 return; 49 } 50 51 try 52 { 53 client = _socket.EndAccept(result); 54 } 55 catch (SocketException e) 56 { 57 if (_disposed || 58 e.SocketErrorCode == SocketError.OperationAborted || 59 e.SocketErrorCode == SocketError.Interrupted) 60 { 61 return; 62 } 63 64 throw; 65 } 66 catch (ObjectDisposedException) 67 { 68 return; 69 } 70 71 ServerSocketState state = new ServerSocketState(client, _receiveBufferSize); 72 try 73 { 74 state.Socket.BeginReceive(state.TransferBuffer, 0, state.TransferBuffer.Length, SocketFlags.None, OnReceive, state); 75 } 76 catch (SocketException) 77 { 78 } 79 80 try 81 { 82 _socket.BeginAccept(OnAccept, null); 83 } 84 catch (SocketException e) 85 { 86 if (_disposed || 87 e.SocketErrorCode == SocketError.OperationAborted || 88 e.SocketErrorCode == SocketError.Interrupted) 89 { 90 return; 91 } 92 93 throw; 94 } 95 catch (ObjectDisposedException) 96 { 97 } 98 } 99 OnReceive(IAsyncResult result)100 private void OnReceive(IAsyncResult result) 101 { 102 ServerSocketState recvState = (ServerSocketState)result.AsyncState; 103 104 try 105 { 106 int bytesReceived = recvState.Socket.EndReceive(result); 107 if (bytesReceived == 0) 108 { 109 recvState.Socket.Dispose(); 110 return; 111 } 112 113 ServerSocketState sendState = new ServerSocketState(recvState, bytesReceived); 114 115 sendState.Socket.BeginSend(sendState.TransferBuffer, 0, bytesReceived, SocketFlags.None, OnSend, sendState); 116 recvState.Socket.BeginReceive( 117 recvState.TransferBuffer, 118 0, 119 recvState.TransferBuffer.Length, 120 SocketFlags.None, 121 OnReceive, 122 recvState); 123 } 124 catch (SocketException) 125 { 126 recvState.Socket.Dispose(); 127 return; 128 } 129 catch (ObjectDisposedException) 130 { 131 return; 132 } 133 } 134 OnSend(IAsyncResult result)135 private void OnSend(IAsyncResult result) 136 { 137 ServerSocketState sendState = (ServerSocketState)result.AsyncState; 138 139 try 140 { 141 int bytesSent = sendState.Socket.EndSend(result); 142 if (bytesSent != sendState.TransferBuffer.Length) 143 { 144 _log.WriteLine("{2} APM: OnSend {0}bytes - expecting {1}bytes.", bytesSent, sendState.TransferBuffer.Length, sendState.Socket.GetHashCode()); 145 } 146 } 147 catch (SocketException) 148 { 149 sendState.Socket.Dispose(); 150 return; 151 } 152 catch (ObjectDisposedException) 153 { 154 return; 155 } 156 } 157 158 private class ServerSocketState 159 { 160 private Socket __socket; 161 private byte[] _buffer; 162 ServerSocketState(Socket _socket, int bufferSize)163 public ServerSocketState(Socket _socket, int bufferSize) 164 { 165 __socket = _socket; 166 _buffer = new byte[bufferSize]; 167 } 168 ServerSocketState(ServerSocketState original, int count)169 public ServerSocketState(ServerSocketState original, int count) 170 { 171 __socket = original.__socket; 172 _buffer = new byte[count]; 173 Buffer.BlockCopy(original._buffer, 0, _buffer, 0, count); 174 } 175 176 public Socket Socket 177 { 178 get { return __socket; } 179 } 180 181 public byte[] TransferBuffer 182 { 183 get { return _buffer; } 184 } 185 } 186 } 187 } 188