/// <summary> /// Start receiving bytes from socket and invoke /// MessageReceived event when each message received. /// Possible exception: /// ArgumentException /// InvalidOperationException /// NotSupportedException /// ObjectDisposedException /// SocketException /// Details at http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receiveasync.aspx /// </summary> public void StartReceiving() { // Check if socket is started receiving already if (!_isReceiving) { _isReceiving = true; } else { return; } try { // Initialize receiving buffer var buffer = new byte[BUFFER_SIZE]; // Initialize receive event args var receiveEventArgs = new SocketAsyncEventArgs(); receiveEventArgs.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE); receiveEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(receiveEventArgs_Completed); // Call ReceiveAsync method, if method returned false // it means the result has returned synchronously if (!InnerSocket.ReceiveAsync(receiveEventArgs)) { ProcessReceive(receiveEventArgs); } } catch (Exception ex) { StopReceiving(); throw ex; } }
/// <summary> /// Use Socket to send string message. /// Possible exception: /// FormatException /// ArgumentException /// InvalidOperationException /// NotSupportedException /// ObjectDisposedException /// SocketException /// </summary> /// <param name="data">message to be sent</param> public void SendAsync(string data) { // If message data contains EOM_MARKER char, // throw exception if (data.Contains(EOM_MARKER)) { throw new Exception("Unallowed chars existed in message"); } // Add End-of-message char at message end. data += EOM_MARKER; // Get UTF8 encoded byte array var bytesdata = encoding.GetBytes(data); // Initialize SendEventArgs var sendEventArgs = new SocketAsyncEventArgs(); sendEventArgs.SetBuffer(bytesdata, 0, bytesdata.Length); sendEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(sendEventArgs_Completed); // Call SendAsync method, if method returned false // it means the result has returned synchronously if (!InnerSocket.SendAsync(sendEventArgs)) { ProcessSend(sendEventArgs); } }
/// <inheritdoc cref="AbstractClientSocket.ExecuteRequest"/> public override byte[] ExecuteRequest ( byte[] request ) { Sure.NotNull(request, nameof(request)); double probability = Probability; if (probability > 0.0 && probability < 1.0) { double value = _random.NextDouble(); if (value < probability) { throw new IrbisNetworkException ( "Broken network event" ); } } byte[] result = InnerSocket.ThrowIfNull().ExecuteRequest(request); return(result); }
/// <summary> /// 使用套接字发送字符串消息 /// 可能异常: /// FormatException /// ArgumentException /// InvalidOperationException /// NotSupportedException /// ObjectDisposedException /// SocketException /// </summary> /// <param name="data">要发送的消息</param> public void SendAsync(string data) { // 如果消息包含分隔符EOM_MARKER, // 抛出异常 if (data.Contains(EOM_MARKER)) { throw new Exception("消息中有不允许的字符"); } // 在消息后加结尾分隔符。 data += EOM_MARKER; // 用UTF8编码成字节数组 var bytesdata = encoding.GetBytes(data); // 初始化发送事件变量SendEventArgs var sendEventArgs = new SocketAsyncEventArgs(); sendEventArgs.SetBuffer(bytesdata, 0, bytesdata.Length); sendEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(sendEventArgs_Completed); // 调用异步发送方法SendAsync,如果方法返回false // 就意味着结果是异步的 if (!InnerSocket.SendAsync(sendEventArgs)) { ProcessSend(sendEventArgs); } }
/// <summary> /// 当接收每一条消息时,开始接收套接字的字节和调用 /// 消息接收事件MessageReceived。 /// 可能异常: /// ArgumentException /// InvalidOperationException /// NotSupportedException /// ObjectDisposedException /// SocketException /// 详情: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receiveasync.aspx /// </summary> public void StartReceiving() { // 检查套接字是否已经开始接收消息 if (!_isReceiving) { _isReceiving = true; } else { return; } try { // 初始化接收缓冲器 var buffer = new byte[BUFFER_SIZE]; // 初始化接收事件变量 var receiveEventArgs = new SocketAsyncEventArgs(); receiveEventArgs.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE); receiveEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(receiveEventArgs_Completed); // 调用异步接收方法ReceiveAsync,如果返回false // 就意味着结果是异步返回的 if (!InnerSocket.ReceiveAsync(receiveEventArgs)) { ProcessReceive(receiveEventArgs); } } catch (Exception ex) { StopReceiving(); throw ex; } }
/// <summary> /// Abort the request. /// </summary> public override void AbortRequest() { AbstractClientSocket innerSocket = InnerSocket .ThrowIfNull("InnerSocket"); innerSocket.AbortRequest(); }
/// <summary> /// 接收状态数据 /// </summary> /// <returns></returns> public byte[] ReceiveState() { byte[] buffer = new byte[4]; InnerSocket.Receive(buffer); return(buffer); //return Encoding.UTF8.GetString(buffer); }
/// <summary> /// 连接 /// </summary> public void Connect() { if (IsConnected) { return; } InnerSocket.Connect(new IPEndPoint(IP, Port)); IsConnected = true; }
/// <summary> /// 接收Body /// </summary> /// <returns></returns> public byte[] ReceiveData() { byte[] lenBytes = new byte[4]; InnerSocket.Receive(lenBytes); string lenString = Encoding.UTF8.GetString(lenBytes); int len = int.Parse(lenString, System.Globalization.NumberStyles.HexNumber); byte[] dataBuffer = new byte[len]; InnerSocket.Receive(dataBuffer); return(dataBuffer); }
public Task MultipleWriteAsync(IList <ArraySegment <byte> > sendBuffers, CancellationToken cancellationToken) { Contract.Assert(this.SupportsMultipleWrite, "This method MUST NOT be used for custom NetworkStream implementations."); if (!m_InOpaqueMode) { // We can't use fast path over SSL return(Task.Factory.FromAsync <IList <ArraySegment <byte> > >(s_BeginMultipleWrite, s_EndMultipleWrite, sendBuffers, this)); } if (WebSocketBase.LoggingEnabled) { Logging.Enter(Logging.WebSockets, this, Methods.MultipleWriteAsync, string.Empty); } bool completedAsynchronously = false; try { cancellationToken.ThrowIfCancellationRequested(); #if DEBUG // When using fast path only one outstanding read is permitted. By switching into opaque mode // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition) // caller takes responsibility for enforcing this constraint. Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Writes) == 1, "Only one outstanding write allowed at any given time."); #endif WebSocketHelpers.ThrowIfConnectionAborted(m_InnerStream, false); m_WriteTaskCompletionSource = new TaskCompletionSource <object>(); m_WriteEventArgs.SetBuffer(null, 0, 0); m_WriteEventArgs.BufferList = sendBuffers; completedAsynchronously = InnerSocket.SendAsync(m_WriteEventArgs); if (!completedAsynchronously) { if (m_WriteEventArgs.SocketError != SocketError.Success) { throw new SocketException(m_WriteEventArgs.SocketError); } return(Task.CompletedTask); } return(m_WriteTaskCompletionSource.Task); } finally { if (WebSocketBase.LoggingEnabled) { Logging.Exit(Logging.WebSockets, this, Methods.MultipleWriteAsync, completedAsynchronously); } } }
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { WebSocketHelpers.ValidateBuffer(buffer, offset, count); if (!m_InOpaqueMode) { return(base.WriteAsync(buffer, offset, count, cancellationToken)); } if (WebSocketBase.LoggingEnabled) { Logging.Enter(Logging.WebSockets, this, Methods.WriteAsync, WebSocketHelpers.GetTraceMsgForParameters(offset, count, cancellationToken)); } bool completedAsynchronously = false; try { cancellationToken.ThrowIfCancellationRequested(); #if DEBUG // When using fast path only one outstanding read is permitted. By switching into opaque mode // via IWebSocketStream.SwitchToOpaqueMode (see more detailed comments in interface definition) // caller takes responsibility for enforcing this constraint. Contract.Assert(Interlocked.Increment(ref m_OutstandingOperations.m_Writes) == 1, "Only one outstanding write allowed at any given time."); #endif WebSocketHelpers.ThrowIfConnectionAborted(m_InnerStream, false); m_WriteTaskCompletionSource = new TaskCompletionSource <object>(); m_WriteEventArgs.BufferList = null; m_WriteEventArgs.SetBuffer(buffer, offset, count); completedAsynchronously = InnerSocket.SendAsync(m_WriteEventArgs); if (!completedAsynchronously) { if (m_WriteEventArgs.SocketError != SocketError.Success) { throw new SocketException(m_WriteEventArgs.SocketError); } return(Task.CompletedTask); } return(m_WriteTaskCompletionSource.Task); } finally { if (WebSocketBase.LoggingEnabled) { Logging.Exit(Logging.WebSockets, this, Methods.WriteAsync, completedAsynchronously); } } }
/// <summary> /// Libera los recursos no utilizados de <see cref="T:System.Net.Sockets.NetworkStream"/> y libera los /// recursos administrados /// </summary> protected override void Dispose(bool disposing) { // Llama al base base.Dispose(disposing); // Libera los recursos if (disposing && !IsDisposed) { bool connected = true; // Indica que se ha liberado IsDisposed = true; // Libera los recursos try { // Libera el socket if (InnerSocket != null) { // Guarda el valor que indica si estaba conectado connected = InnerSocket.Connected; // Libera el socket if (connected) { Process(delegate { InnerSocket.Shutdown(SocketShutdown.Both); InnerSocket.Close(300000); } ); } } // Libera el stream Process(delegate { if (InnerStream != null) { InnerStream.Dispose(); } } ); } finally { Release(ExpectEndReply); } // Si no estaba conectado, lanza una excepción if (!connected) { throw new Exceptions.FtpTransportException("Stream cerrado anteriormente por el servidor"); } } }
private bool disposedValue = false; // 要检测冗余调用 /// <summary> /// Dispose /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { InnerSocket.Dispose(); } // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。 // TODO: 将大型字段设置为 null。 disposedValue = true; } }
/// <summary> /// Send request to server and receive answer. /// </summary> public override byte[] ExecuteRequest ( byte[] request ) { Func <byte[], byte[]> func = InnerSocket.ThrowIfNull().ExecuteRequest; byte[] result = RetryManager.Try ( func, request ); return(result); }
/// <inheritdoc cref="AbstractClientSocket.ExecuteRequest" /> public override byte[] ExecuteRequest ( byte[] request ) { Sure.NotNull(request, nameof(request)); int delay = Delay; if (delay > 0) { //ThreadUtility.Sleep(delay); Thread.Sleep(delay); } byte[] result = InnerSocket.ThrowIfNull().ExecuteRequest(request); return(result); }
/// <summary> /// 异步连接套接字到终端。 /// 可能的异常: /// ArgumentException /// ArgumentNullException /// InvalidOperationException /// SocketException /// NotSupportedException /// ObjectDisposedException /// SecurityException /// 详情: http://msdn.microsoft.com/en-us/library/bb538102.aspx /// </summary> /// <param name="ep">远程终端</param> public void ConnectAsync(EndPoint ep) { if (InnerSocket.Connected) { return; } // 初始化socketAsyncEventArgs对象 // 设置远程连接终端 var connectEventArgs = new SocketAsyncEventArgs(); connectEventArgs.RemoteEndPoint = ep; connectEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(connectEventArgs_Completed); // 调用ConnectAsync方法, 如果该方法返回false // 它就意味着返回的结果是异步的 if (!InnerSocket.ConnectAsync(connectEventArgs)) { // 调用方法来处理连接结果 ProcessConnect(connectEventArgs); } }
/// <summary> /// Connect socket to endpoint asynchronously. /// Possible exception: /// ArgumentException /// ArgumentNullException /// InvalidOperationException /// SocketException /// NotSupportedException /// ObjectDisposedException /// SecurityException /// Details at: http://msdn.microsoft.com/en-us/library/bb538102.aspx /// </summary> /// <param name="ep">remote endpoint</param> public void ConnectAsync(EndPoint ep) { if (InnerSocket.Connected) { return; } // Initialize socketAsyncEventArgs // Set remote connect endpoint var connectEventArgs = new SocketAsyncEventArgs(); connectEventArgs.RemoteEndPoint = ep; connectEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(connectEventArgs_Completed); // Call ConnectAsync method, if method returned false // it means the result has returned synchronously if (!InnerSocket.ConnectAsync(connectEventArgs)) { // Call method to handle connect result ProcessConnect(connectEventArgs); } }
/// <summary> /// Send request to server and receive answer. /// </summary> public override byte[] ExecuteRequest ( byte[] request ) { Sure.NotNull(request, "request"); AbstractClientSocket innerSocket = InnerSocket .ThrowIfNull("InnerSocket"); byte[] result; try { result = innerSocket.ExecuteRequest(request); } catch (Exception exception) { Log.TraceException ( "LoggingClientSocket::ExecuteRequest", exception ); Task.Factory.StartNew ( () => _DumpException(exception) ); throw; } Task.Factory.StartNew ( () => _DumpPackets(request, result) ); return(result); }
// 关闭套接字 public void Close() { InnerSocket.Close(); }
private void ProcessReceive(SocketAsyncEventArgs e) { // 当出错时,调用消息接收事件 // 来传递错误信息给用户 if (e.SocketError != SocketError.Success) { StopReceiving(); OnMessageReceived(null, new SocketException((int)e.SocketError)); return; } try { #region String Decoding // 解码字节成字符串 // 注意UTF-8编码是可变长编码的,我们需要检查字节 // 数组尾部,以防把一个字母分成两个。 string receivestr = ""; // 尝试解码字符串 try { receivestr = encoding.GetString(e.Buffer, 0, taillength + e.BytesTransferred); // 如果解码成功,重设尾部长度 taillength = 0; } // 如果取得解码异常,删除数组尾部,并重新解码 catch (DecoderFallbackException ex) { try{ receivestr = encoding.GetString(e.Buffer, 0, taillength + e.BytesTransferred - ex.BytesUnknown.Length); // 重设尾部长度 taillength = ex.BytesUnknown.Length; ex.BytesUnknown.CopyTo(e.Buffer, 0); } // 如果还出现解码异常,就停止接收 catch (DecoderFallbackException ex2) { throw new Exception("Message decode failed.", ex2); } #endregion } // 检查消息是否结束 int eompos = receivestr.IndexOf(EOM_MARKER); while (eompos != -1) { // 组合成一条完整的消息 receivemessage += receivestr.Substring(0, eompos); // 激活接收的消息 OnMessageReceived(receivemessage, null); // 取得剩下的字符串 receivemessage = ""; receivestr = receivestr.Substring(eompos + 1, receivestr.Length - eompos - 1); // 检查字符串是否还有分隔符 eompos = receivestr.IndexOf(EOM_MARKER); } receivemessage += receivestr; // 停止接收 if (!_isReceiving) { return; } // 重设缓冲器开始地址 e.SetBuffer(taillength, BUFFER_SIZE - taillength); // 继续接收 if (!InnerSocket.ReceiveAsync(e)) { ProcessReceive(e); } } catch (Exception ex) { // 通过消息接收事件返回错误 OnMessageReceived(null, ex); StopReceiving(); } }
/// <inheritdoc cref="AbstractClientSocket.AbortRequest" /> public override void AbortRequest() { InnerSocket.ThrowIfNull().AbortRequest(); }
private void ProcessReceive(SocketAsyncEventArgs e) { // When got Error, invoke MessageReceived event // to pass the error info to user if (e.SocketError != SocketError.Success) { StopReceiving(); OnMessageReceived(null, new SocketException((int)e.SocketError)); return; } try { #region String Decoding // Decoding bytes to string. // Note that UTF-8 is variable-length encode, we need check the byte // array tail in case of separating one character into two. string receivestr = ""; // Try decode string try { receivestr = encoding.GetString(e.Buffer, 0, taillength + e.BytesTransferred); // If decode successful, reset tail length taillength = 0; } // If got decode exception, remove the array tail and re decode catch (DecoderFallbackException ex) { try{ receivestr = encoding.GetString(e.Buffer, 0, taillength + e.BytesTransferred - ex.BytesUnknown.Length); // reset tail length taillength = ex.BytesUnknown.Length; ex.BytesUnknown.CopyTo(e.Buffer, 0); } // If still got decode exception, stop receiving. catch (DecoderFallbackException ex2) { throw new Exception("Message decode failed.", ex2); } #endregion } // Check if message ended int eompos = receivestr.IndexOf(EOM_MARKER); while (eompos != -1) { // Compose a complete message receivemessage += receivestr.Substring(0, eompos); // Notify message received OnMessageReceived(receivemessage, null); // Get the remaining string receivemessage = ""; receivestr = receivestr.Substring(eompos + 1, receivestr.Length - eompos - 1); // Check if it still has EOM in string eompos = receivestr.IndexOf(EOM_MARKER); } receivemessage += receivestr; // Stop receiving. if (!_isReceiving) { return; } // Reset buffer offset e.SetBuffer(taillength, BUFFER_SIZE - taillength); // Keep receiving if (!InnerSocket.ReceiveAsync(e)) { ProcessReceive(e); } } catch (Exception ex) { // Return error through MessageReceived event OnMessageReceived(null, ex); StopReceiving(); } }
/// <summary> /// 发送请求 /// </summary> /// <param name="request"></param> public void SendRequest(string request) { InnerSocket.Send(request.ToAdbRequest()); }