/// <summary> /// Start the server (synchronous) /// </summary> /// <returns>'true' if the server was successfully started, 'false' if the server failed to start</returns> public virtual bool Start() { if (IsStarted) { return(false); } // Setup event args _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive); _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketArgs(SocketAsyncOperation.Send); _sendEventArg.Completed += OnAsyncCompleted; // Create a new server socket Socket = CreateSocket(); // Apply the option: reuse address Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress); // Apply the option: exclusive address use Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse); // Apply the option: dual mode (this option must be applied before recieving) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode(OptionDualMode); } // Bind the server socket to the IP endpoint Socket.Bind(Endpoint); // Refresh the endpoint property based on the actual endpoint created Endpoint = (IPEndPoint)Socket.LocalEndPoint; // Call the server starting handler OnStarting(); // Prepare receive endpoint _receiveEndpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; DatagramsSent = 0; DatagramsReceived = 0; // Update the started flag IsStarted = true; // Call the server started handler OnStarted(); return(true); }
private SocketArgs InitializeEventArgs(SocketAsyncOperation operation) { // Pre-allocate a set of reusable SocketAsyncEventArgs SocketArgs eventArg = new SocketArgs(operation); eventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object if (operation == SocketAsyncOperation.Receive) { _bufferManager.SetBuffer(eventArg); } return(eventArg); }
/// <summary> /// Connect the client (asynchronous) /// </summary> /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns> public virtual bool ConnectAsync() { if (IsConnected || IsConnecting) { return(false); } // Setup event args _connectEventArg = new SocketAsyncEventArgs(); _connectEventArg.RemoteEndPoint = Endpoint; _connectEventArg.Completed += OnAsyncCompleted; _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive); _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketArgs(SocketAsyncOperation.Send); _sendEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = CreateSocket(); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode(OptionDualMode); } // Update the connecting flag IsConnecting = true; // Call the client connecting handler OnConnecting(); // Async connect to the server if (!Socket.ConnectAsync(_connectEventArg)) { ProcessConnect(_connectEventArg); } return(true); }
/// <summary> /// Connect the client (synchronous) /// </summary> /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns> public virtual bool Connect() { if (IsConnected) { return(false); } // Setup event args _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive); _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketArgs(SocketAsyncOperation.Send); _sendEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = CreateSocket(); // Apply the option: reuse address Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionReuseAddress); // Apply the option: exclusive address use Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, OptionExclusiveAddressUse); // Apply the option: dual mode (this option must be applied before recieving/sending) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode(OptionDualMode); } // Call the client connecting handler OnConnecting(); try { // Bind the acceptor socket to the IP endpoint if (OptionMulticast) { Socket.Bind(Endpoint); } else { var endpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0); Socket.Bind(endpoint); } } catch (SocketException ex) { // Call the client error handler SendError("Connect", ex.SocketErrorCode); // Reset event args _receiveEventArg.Completed -= OnAsyncCompleted; _sendEventArg.Completed -= OnAsyncCompleted; // Call the client disconnecting handler OnDisconnecting(); // Close the client socket Socket.Close(); // Dispose the client socket Socket.Dispose(); // Dispose event arguments _receiveEventArg.Dispose(); _sendEventArg.Dispose(); // Call the client disconnected handler OnDisconnected(); return(false); } // Prepare receive endpoint _receiveEndpoint = new IPEndPoint((Endpoint.AddressFamily == AddressFamily.InterNetworkV6) ? IPAddress.IPv6Any : IPAddress.Any, 0); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; DatagramsSent = 0; DatagramsReceived = 0; // Update the connected flag IsConnected = true; // Call the client connected handler OnConnected(); return(true); }
/// <summary> /// Connect the client (synchronous) /// </summary> /// <remarks> /// Please note that synchronous connect will not receive data automatically! /// You should use Receive() or ReceiveAsync() method manually after successful connection. /// </remarks> /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns> public virtual bool Connect() { if (IsConnected || IsConnecting) { return(false); } // Setup event args _connectEventArg = new SocketAsyncEventArgs(); _connectEventArg.RemoteEndPoint = Endpoint; _connectEventArg.Completed += OnAsyncCompleted; _receiveEventArg = new SocketArgs(SocketAsyncOperation.Receive); _receiveEventArg.SetBuffer(new byte[OptionReceiveBufferSize], 0, OptionReceiveBufferSize); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketArgs(SocketAsyncOperation.Send); _sendEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = CreateSocket(); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode(OptionDualMode); } // Call the client connecting handler OnConnecting(); try { // Connect to the server Socket.Connect(Endpoint); } catch (SocketException ex) { // Call the client error handler SendError("Connect", ex.SocketErrorCode); // Reset event args _connectEventArg.Completed -= OnAsyncCompleted; _receiveEventArg.Completed -= OnAsyncCompleted; _sendEventArg.Completed -= OnAsyncCompleted; // Call the client disconnecting handler OnDisconnecting(); // Close the client socket Socket.Close(); // Dispose the client socket Socket.Dispose(); // Dispose event arguments _connectEventArg.Dispose(); _receiveEventArg.Dispose(); _sendEventArg.Dispose(); // Call the client disconnected handler OnDisconnected(); return(false); } // Apply the option: keep alive (keepAliveTime = 10min, keepAliveInterval = 60s) if (OptionKeepAlive) { Socket.SetKeepAlive(600, 60); } // Apply the option: no delay if (OptionNoDelay) { Socket.NoDelay = true; } // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; // Update the connected flag IsConnected = true; // Call the client connected handler OnConnected(); // Call the empty send buffer handler if (_sendQueue.IsEmpty) { OnEmpty(); } return(true); }