protected void KickCompleted(SocketAsyncEventArgsExt argz) { try { if (argz.SocketError == SocketError.Success) { if (argz.LastOperation == SocketAsyncOperation.Disconnect) { kickPool.Put(argz); HandleError(SocketError.Disconnecting); } else { if (!socket.DisconnectAsync(argz)) { kickPool.Put(argz); HandleError(SocketError.Disconnecting); } } } else { HandleError(argz.SocketError); kickPool.Put(argz); } // kicking = false; } catch (Exception e) { ProgramLog.Log(e, "Exception in connection disconnect callback"); } }
protected void SendCompleted(SocketAsyncEventArgsExt argz) { try { MessageSendCompleted(); } catch (Exception e) { ProgramLog.Log(e, "Exception in connection send callback"); } try { //ProgramLog.Debug.Log ("SendCompleted {"); if (argz.SocketError != SocketError.Success) { HandleError(argz.SocketError); sendPool.Put(argz); } else { lock (sendQueue) { // if (kicking) // { // sendPool.Put (argz); // sending = false; // return; // } TxListClear(); sending = SendMore(argz); if (!sending && argz.conn != null) { sendPool.Put(argz); } } } //ProgramLog.Debug.Log ("} SendCompleted " + sending); } catch (Exception e) { ProgramLog.Log(e, "Exception in connection send callback"); } }
public void Put(SocketAsyncEventArgsExt args) { // ProgramLog.Debug.Log ("Put"); if (!(args is T)) { ProgramLog.Error.Log("ArgsPool type mismatch."); return; } lock (this) { if (args.conn == null) { ProgramLog.Error.Log("{0} freed twice.", typeof(T).Name); return; } args.BufferList = null; args.conn = null; Push((T)args); } }
protected void KickCompleted(SocketAsyncEventArgsExt argz) { try { if (argz.SocketError == SocketError.Success) { if (argz.LastOperation == SocketAsyncOperation.Disconnect) { kickPool.Put(argz); HandleError(SocketError.Disconnecting); } else { if (!socket.DisconnectAsync(argz)) { kickPool.Put(argz); HandleError(SocketError.Disconnecting); } } } else { HandleError(argz.SocketError); kickPool.Put(argz); } // kicking = false; } catch (ObjectDisposedException) { } catch (Exception e) { Tools.WriteLine("Exception in connection disconnect callback: {0}", e); } }
protected void ReceiveCompleted(SocketAsyncEventArgsExt argz) { try { if (argz.SocketError != SocketError.Success) { //ProgramLog.Debug.Log ("Bytes received: {0}", argz.BytesTransferred); var err = argz.SocketError; receiving = false; recvPool.Put(argz); HandleError(err); } else if (argz.BytesTransferred == 0) { //ProgramLog.Debug.Log ("Clean connection shutdown. {0}", socket.Connected); receiving = false; recvPool.Put(argz); HandleError(SocketError.Disconnecting); } else { var bytes = argz.BytesTransferred; receiving = false; if (kicking) { recvPool.Put(argz); return; } while (!receiving) { recvBytes += bytes; BytesReceived += bytes; ProcessRead(); if (kicking) { receiving = false; break; } var left = recvBuffer.Length - recvBytes; if (left <= 0) { return; } argz.SetBuffer(recvBuffer, recvBytes, left); try { receiving = socket.ReceiveAsync(argz); } catch (ObjectDisposedException) { receiving = false; } if (receiving) { bytes = argz.BytesTransferred; } } if (!receiving) { recvPool.Put(argz); } } } catch (Exception e) { ProgramLog.Log(e, "Exception in connection receive callback"); } }
//#if BANDWIDTH_ANALYSIS // public static int[] packetsPerMessage = new int [255]; // public static long[] bytesPerMessage = new long [255]; //#endif protected bool SendMore(SocketAsyncEventArgsExt args, bool flush = false) { flush |= txBuffer == null; try { var queued = false; var escape = false; while (sendQueue.Count > 0 && txListBytes < 2880 && !escape) { var msg = sendQueue.PopFront(); switch (msg.kind) { case Message.BYTES: { var data = (byte[])msg.content; txList.Add(new ArraySegment <byte>(data)); txListBytes += data.Length; queueSize -= data.Length + ARRAY_OBJECT_OVERHEAD; //ProgramLog.Debug.Log ("{1}: Adding bytes {0}", data.Length, Thread.CurrentThread.IsThreadPoolThread); break; } case Message.SEGMENT: { var len = msg.param; var txc = txList.Count; int wraparound = 0; if (txc > 0 && txList[txc - 1].Array == txBuffer) { var seg = txList[txc - 1]; var nlen = seg.Count + len; var nseg = new ArraySegment <byte>(txBuffer, seg.Offset, Math.Min(nlen, txBuffer.Length - seg.Offset)); //ProgramLog.Debug.Log ("{5}: Coalescing {0}, {1} and {2}, {3} [{4}]", seg.Offset, seg.Count, (txHead + txPrepared) % txBuffer.Length, len, nseg.Count, Thread.CurrentThread.IsThreadPoolThread); txList[txc - 1] = nseg; wraparound = nlen - nseg.Count; } else { var offset = (txHead + txPrepared) % txBuffer.Length; //ProgramLog.Debug.Log ("{2}: Adding segment {0}, {1}", offset, len, Thread.CurrentThread.IsThreadPoolThread); var nseg = new ArraySegment <byte>(txBuffer, offset, Math.Min(len, txBuffer.Length - offset)); txList.Add(nseg); wraparound = len - nseg.Count; } if (wraparound > 0) { txList.Add(new ArraySegment <byte>(txBuffer, 0, wraparound)); } txPrepared += len; txListBytes += len; queueSize -= len; break; } default: { var data = SerializeMessage(msg); txList.Add(data); txListBytes += data.Count; //ProgramLog.Debug.Log ("{1}: Adding custom {0}", data.Count, Thread.CurrentThread.IsThreadPoolThread); escape = true; break; } case Message.KICK: { if ((!queued) /*&& (! sending)*/ && args != null && args.conn != null) { sendPool.Put(args); } //txList.Clear (); //txListBytes = 0; var kickArgs = kickPool.Take(this); var data = (byte[])msg.content; kickArgs.SetBuffer(data, 0, data.Length); if (!socket.SendAsync(kickArgs)) { if (!socket.DisconnectAsync(kickArgs)) { KickCompleted(kickArgs); } } return(false); } } } if (escape) { flush = true; } if (txListBytes >= 1450 || (txListBytes > 0 && flush)) { if (args == null) { args = sendPool.Take(this); } if (txList.Count > 1) { args.SetBuffer(null, 0, 0); args.BufferList = txList; } else { var seg = txList[0]; args.BufferList = null; args.SetBuffer(seg.Array, seg.Offset, seg.Count); } // var o = 0; // for (int i = 0; i < txList.Count; i++) // o += 40 * (1 + txList[i].Count / 1460) + txList[i].Count; // var n = 40 * (1 + txListBytes / 1460) + txListBytes; // Interlocked.Add (ref totalBytesBuffered, (long)n); // Interlocked.Add (ref totalBytesUnbuffered, (long)o); BytesSent += n; try { queued = socket.SendAsync(args); } finally { if (!queued) { TxListClear(); if (escape) { MessageSendCompleted(); } } } } return(queued); } catch (SocketException e) { HandleError(e.SocketErrorCode); } catch (ObjectDisposedException) { HandleError(SocketError.OperationAborted); } return(false); }
private void ProcessConnectCompleted(bool synchronous) { this.sendArgs.Completed -= this.OnTcpConnectCompleted; if (this.sendArgs.SocketError == SocketError.Success) { this.receiveArgs = new SocketAsyncEventArgsExt(); this.receiveArgs.Completed += this.OnReceiveCompleted; this.sendArgs.Completed -= this.OnTcpConnectCompleted; this.sendArgs.Completed += this.OnSendCompleted; this.StartWebSocketHandshake(_customHeaders); // this is the entry point to a version specific derived class } else { this.FailWebSocketConnection(this.sendArgs.ConnectByNameError, synchronous); } }
public void Start(Dictionary<string, string> customHeaders) { if (customHeaders != null) this._customHeaders = customHeaders; this.sendArgs = new SocketAsyncEventArgsExt(); this.sendArgs.RemoteEndPoint = new DnsEndPoint(this.Uri.DnsSafeHost, this.Uri.Port); #if !SILVERLIGHT #else this.sendArgs.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Http; #endif this.sendArgs.Completed += this.OnTcpConnectCompleted; this.socket = new SecureSocketProxy("wss".Equals(Uri.Scheme, StringComparison.OrdinalIgnoreCase)); this.socket.NoDelay = this.noDelay; if (!this.socket.ConnectAsync(this.sendArgs)) { this.ProcessConnectCompleted(true); } }
/// <summary> /// Begins an asynchronous read operation that reads data from the stream and stores /// it in the specified array. /// </summary> /// <param name="args">A user-defined object that contains information about the read /// operation. This object is passed to the asyncCallback delegate when the operation /// completes.</param> /// <returns>Return true if state of receive is success.</returns> public bool ReceiveAsync(SocketAsyncEventArgsExt args) { if (_isSecure) { _sslStream.BeginRead(args.Buffer, args.Offset, args.Count, ReceiveComplete, args); return true; } return _socket.ReceiveAsync(args); }