public NetworkDataBuffer ReceiveBinary() { NetworkDataBuffer result = new NetworkDataBuffer(); if (!webSocketNetwork.WsHandshaked) { return(result); } NetworkDataBuffer cache = new NetworkDataBuffer(); // Receive WebSocket frame data while (!webSocketNetwork.WsReceived) { Int32 required = webSocketNetwork.RequiredReceiveFrameSize(); cache.Resize(required); Int32 received = (Int32)base.Receive(cache.Data, 0, required); if (received != required) { return(result); } webSocketNetwork.PrepareReceiveFrame(cache.Data, 0, received); } // Copy WebSocket frame data result.Append(webSocketNetwork.WsReceiveBuffer.ToArray(), webSocketNetwork.WsHeaderSize, webSocketNetwork.WsHeaderSize + webSocketNetwork.WsPayloadSize); webSocketNetwork.PrepareReceiveFrame(null, 0, 0); return(result); }
/// <summary> /// Start the server (synchronous) /// </summary> /// <returns>'true' if the server was successfully started, 'false' if the server failed to start</returns> public override Boolean Start() { if (IsStarted) { return(false); } // Setup buffers _receiveBuffer = new NetworkDataBuffer(); _sendBuffer = new NetworkDataBuffer(); // Setup event args _receiveEventArg = new SocketAsyncEventArgs(); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketAsyncEventArgs(); _sendEventArg.Completed += OnAsyncCompleted; // Create a new server socket Socket = new Socket(Endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp); // Update the server socket disposed flag IsSocketDisposed = false; // 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; // Prepare receive endpoint _receiveEndpoint = new IPEndPoint(Endpoint.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0); // Prepare receive & send buffers _receiveBuffer.Reserve(OptionReceiveBufferSize); // 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); }
/// <summary> /// Connect the client (asynchronous) /// </summary> /// <returns>'true' if the client was successfully connected, 'false' if the client failed to connect</returns> public override Boolean ConnectAsync() { if (IsConnected || IsConnecting) { return(false); } // Setup buffers receiveBuffer = new NetworkDataBuffer(); sendBufferMain = new NetworkDataBuffer(); sendBuffer = new NetworkDataBuffer(); // Setup event args connectEventArg = new SocketAsyncEventArgs { RemoteEndPoint = Endpoint }; connectEventArg.Completed += OnAsyncCompleted; _receiveEventArg = new SocketAsyncEventArgs(); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketAsyncEventArgs(); _sendEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode = OptionDualMode; } // Async connect to the server IsConnecting = true; if (!Socket.ConnectAsync(connectEventArg)) { ProcessConnect(connectEventArg); } return(true); }
/// <summary> /// Connect the session /// </summary> /// <param name="socket">Session socket</param> public override void Connect(Socket socket) { if (IsConnected) { throw new AlreadyInitializedException("Already connected"); } Socket = socket; // Update the session socket disposed flag IsSocketDisposed = false; // Setup buffers _receiveBuffer = new NetworkDataBuffer(); sendBufferMain = new NetworkDataBuffer(); sendBufferFlush = new NetworkDataBuffer(); // Apply the option: keep alive if (Server.OptionKeepAlive) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); } // Apply the option: no delay if (Server.OptionNoDelay) { Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } // Prepare receive & send buffers _receiveBuffer.Reserve(OptionReceiveBufferSize); sendBufferMain.Reserve(OptionSendBufferSize); sendBufferFlush.Reserve(OptionSendBufferSize); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; // Update the connected flag IsConnected = true; // Call the session connected handler OnConnected(); // Call the session connected handler in the server Server.OnConnectedInternal(this); try { // Create SSL stream _sslStreamId = Guid.NewGuid(); _sslStream = Server.Context.CertificateValidationCallback is not null ? new SslStream(new NetworkStream(Socket, false), false, Server.Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); // Begin the SSL handshake _sslStream.BeginAuthenticateAsServer(Server.Context.Certificate, Server.Context.ClientCertificateRequired, Server.Context.Protocols, false, ProcessHandshake, _sslStreamId); } catch (Exception) { SendError(SocketError.NotConnected); Disconnect(); } }
/// <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 override Boolean Connect() { if (IsConnected || IsHandshaked || IsConnecting || IsHandshaking) { return(false); } // Setup buffers receiveBuffer = new NetworkDataBuffer(); sendBufferMain = new NetworkDataBuffer(); sendBuffer = new NetworkDataBuffer(); // Setup event args connectEventArg = new SocketAsyncEventArgs { RemoteEndPoint = Endpoint }; connectEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode = OptionDualMode; } try { // Connect to the server Socket.Connect(Endpoint); } catch (SocketException ex) { // Close the client socket Socket.Close(); // Dispose the client socket Socket.Dispose(); // Dispose event arguments connectEventArg.Dispose(); // Call the client disconnected handler SendError(ex.SocketErrorCode); OnDisconnected(); return(false); } // Update the client socket disposed flag IsSocketDisposed = false; // Apply the option: keep alive if (OptionKeepAlive) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); } // Apply the option: no delay if (OptionNoDelay) { Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } // Prepare receive & send buffers receiveBuffer.Reserve(OptionReceiveBufferSize); sendBufferMain.Reserve(OptionSendBufferSize); sendBuffer.Reserve(OptionSendBufferSize); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; // Update the connected flag IsConnected = true; // Call the client connected handler OnConnected(); try { // Create SSL stream _sslStreamId = Guid.NewGuid(); _sslStream = Context.CertificateValidationCallback is not null ? new SslStream(new NetworkStream(Socket, false), false, Context.CertificateValidationCallback) : new SslStream(new NetworkStream(Socket, false), false); // SSL handshake _sslStream.AuthenticateAsClient(Address, Context.Certificates ?? new X509CertificateCollection(new[] { Context.Certificate }), Context.Protocols, true); } catch (Exception) { SendError(SocketError.NotConnected); DisconnectAsync(); return(false); } // Update the handshaked flag IsHandshaked = true; // Call the session handshaked handler OnHandshaked(); // Call the empty send buffer handler if (sendBufferMain.IsEmpty) { OnEmpty(); } 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 override Boolean Connect() { if (IsConnected || IsConnecting) { return(false); } // Setup buffers receiveBuffer = new NetworkDataBuffer(); sendBufferMain = new NetworkDataBuffer(); sendBuffer = new NetworkDataBuffer(); // Setup event args connectEventArg = new SocketAsyncEventArgs { RemoteEndPoint = Endpoint }; connectEventArg.Completed += OnAsyncCompleted; _receiveEventArg = new SocketAsyncEventArgs(); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketAsyncEventArgs(); _sendEventArg.Completed += OnAsyncCompleted; // Create a new client socket Socket = new Socket(Endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Apply the option: dual mode (this option must be applied before connecting) if (Socket.AddressFamily == AddressFamily.InterNetworkV6) { Socket.DualMode = OptionDualMode; } try { // Connect to the server Socket.Connect(Endpoint); } catch (SocketException ex) { // 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 SendError(ex.SocketErrorCode); OnDisconnected(); return(false); } // Update the client socket disposed flag IsSocketDisposed = false; // Apply the option: keep alive if (OptionKeepAlive) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); } // Apply the option: no delay if (OptionNoDelay) { Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } // Prepare receive & send buffers receiveBuffer.Reserve(OptionReceiveBufferSize); sendBufferMain.Reserve(OptionSendBufferSize); sendBuffer.Reserve(OptionSendBufferSize); // 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 (sendBufferMain.IsEmpty) { OnEmpty(); } return(true); }
/// <summary> /// Connect the session /// </summary> /// <param name="socket">Session socket</param> public override void Connect(Socket socket) { if (IsConnected) { throw new AlreadyInitializedException("Already connected"); } Socket = socket; // Update the session socket disposed flag IsSocketDisposed = false; // Setup buffers _receiveBuffer = new NetworkDataBuffer(); sendBufferMain = new NetworkDataBuffer(); sendBufferFlush = new NetworkDataBuffer(); // Setup event args _receiveEventArg = new SocketAsyncEventArgs(); _receiveEventArg.Completed += OnAsyncCompleted; _sendEventArg = new SocketAsyncEventArgs(); _sendEventArg.Completed += OnAsyncCompleted; // Apply the option: keep alive if (Server.OptionKeepAlive) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); } // Apply the option: no delay if (Server.OptionNoDelay) { Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); } // Prepare receive & send buffers _receiveBuffer.Reserve(OptionReceiveBufferSize); sendBufferMain.Reserve(OptionSendBufferSize); sendBufferFlush.Reserve(OptionSendBufferSize); // Reset statistic BytesPending = 0; BytesSending = 0; BytesSent = 0; BytesReceived = 0; // Update the connected flag IsConnected = true; // Call the session connected handler OnConnected(); // Call the session connected handler in the server Server.OnConnectedInternal(this); // Call the empty send buffer handler if (sendBufferMain.IsEmpty) { OnEmpty(); } // Try to receive something from the client TryReceive(); }