/// <summary> /// Create a new socket and try to connect to a remote client/server. /// </summary> /// <param name="endPoint">Endpoint that should get connected.</param> /// <returns>Connected client.</returns> /// <exception cref="SocketException">If connection fails.</exception> protected virtual ClientContext CreateAndConnect(IPEndPoint endPoint) { var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); socket.Connect(endPoint); return(new ClientContext(socket, BufferPool.Dequeue(), _factory.CreateNewContext(endPoint))); }
/// <summary> /// Create a new context and allocate it's buffer. /// </summary> /// <param name="socket">The socket.</param> /// <exception cref="InvalidOperationException">Could not allocate new buffer.</exception> /// <exception cref="System.Net.Sockets.SocketException">Could not read from socket.</exception> /// <exception cref="System.ObjectDisposedException">Socket have been disposed.</exception> protected virtual void SetupNewContext(Socket socket) { var context = new ClientContext(socket, BufferPool.Dequeue(), _factory.CreateNewContext(socket.RemoteEndPoint)); if (context.Buffer == null) { throw new InvalidOperationException("Could not allocate new buffer."); } socket.BeginReceive(context.Buffer, 0, context.Buffer.Length, SocketFlags.None, OnReceive, context); }
/// <summary> /// Start transport. /// </summary> /// <exception cref="ArgumentException"><see cref="EndPoint"/> is not of the type expected by the transport implementation</exception> /// <exception cref="ArgumentNullException"><c>endPoint</c> is null.</exception> public void Start() { if (BufferPool == null) { BufferPool = new ObjectPool <byte[]>(() => new byte[65535]); } byte[] buffer = BufferPool.Dequeue(); _socket = CreateSocket(); _socket.Bind(_listeningPoint); _logger.Trace("BeginReceiveFrom"); EndPoint ep = new IPEndPoint(_listeningPoint.Address, _listeningPoint.Port); _socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ep, OnRead, buffer); }
/// <summary> /// Received a message from remote end point. /// </summary> /// <param name="ar"></param> private void OnRead(IAsyncResult ar) { var buffer = (byte[])ar.AsyncState; EndPoint endPoint = new IPEndPoint(IPAddress.Any, 3929); int bytesRead = 0; bool isKeepAlive = true; try { _logger.Trace("_socket.EndReceiveFrom"); bytesRead = _socket.EndReceiveFrom(ar, ref endPoint); if (bytesRead <= 4) { for (int i = 0; i < bytesRead; ++i) { if (buffer[i] != '\r' && buffer[i] != '\n') { isKeepAlive = false; break; } } } else { isKeepAlive = false; } if (!isKeepAlive) { _logger.Debug("Received " + bytesRead + " bytes from " + endPoint + ":\r\n" + Encoding.ASCII.GetString(buffer, 0, bytesRead)); } } catch (Exception err) { _logger.Warning("EndReceiveFrom failed: " + err); } // begin receiving another packet before starting to process this one byte[] newBuffer = BufferPool.Dequeue(); try { EndPoint localEndPoint = new IPEndPoint(_listeningPoint.Address, _listeningPoint.Port); _socket.BeginReceiveFrom(newBuffer, 0, newBuffer.Length, SocketFlags.None, ref localEndPoint, OnRead, newBuffer); } catch (Exception err) { _logger.Warning("BeginReceiveFrom failed, closing socket. Exception: " + err); BufferPool.Enqueue(newBuffer); BufferPool.Enqueue(buffer); _socket.Close(); return; } if (bytesRead == 0 || isKeepAlive) { BufferPool.Enqueue(buffer); return; } // Parse buffer. MessageFactoryContext factoryContext = _parsers.CreateNewContext(endPoint); try { int offset = factoryContext.Parse(buffer, 0, bytesRead); if (offset != bytesRead) { _logger.Error("Failed to parse complete message"); } } finally { BufferPool.Enqueue(buffer); _parsers.Release(factoryContext); } }