/// <summary> /// Private implementation of the Transmit() method that implements an /// option that disables queuing for the message passed. /// </summary> /// <param name="toEP">The target endpoint.</param> /// <param name="msg">The message.</param> /// <param name="queue">Indicates whether queuing should be enabled for this message.</param> private void Transmit(ChannelEP toEP, Msg msg, bool queue) { msg._SetToChannel(toEP); msg._SetFromChannel(localEP); msg._Trace(router, 2, "TCP: Send", null); // Serialize the message here rather than within the lock // below for better multiprocessor performance. Serialize(msg); // Initiate transmission of the message or queue it if other // messages are awaiting transmission (if queuing is enabled). try { using (TimedLock.Lock(router.SyncRoot)) { if (!connected || sending) { Enqueue(msg); return; } // If there are already messages in the queue then add this // message to the end of the queue and then dequeue a message // from the front of the queue and send it. if (queue && sendQueue.Count > 0) { Enqueue(msg); msg = Dequeue(); } // Initiate message transmission sendBuf = msg._MsgFrame; sending = true; sendPos = 0; cbSend = sendBuf.Length; sock.BeginSend(sendBuf, sendPos, cbSend, SocketFlags.None, onSend, null); } } catch (Exception e) { TraceException(e); router.OnTcpClose(this); Close(); } }
public int Send(byte[] buf) { Reset(); sock.BeginSend(buf, 0, buf.Length, SocketFlags.None, onSendBuf, null); asyncEvent.WaitOne(MaxWaitTime, false); Verify(); return(cbTransfer); }
/// <summary> /// Initiates the transmission of bytes from a buffer to the remote side of the connection. /// </summary> /// <param name="buffer">The source buffer.</param> /// <param name="offset">Index of the first byte to be transmitted.</param> /// <param name="count">Number of bytes to be transmitted.</param> /// <param name="callback">The delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state.</param> /// <returns> /// An <see cref="IAsyncResult" /> instance to be used to track the progress of the /// operation and to eventually be passed to the <see cref="EndSend" /> method. /// </returns> /// <exception cref="InvalidOperationException">Thrown if the socket is not connected or if another send operation is already pending for TCP connections.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="buffer" /> is <c>null</c>.</exception> /// <exception cref="IndexOutOfRangeException">Thrown if <paramref name="offset" /> and <paramref name="count" /> specify bytes outside of the <paramref name="buffer" />.</exception> /// <remarks> /// <note> /// Only one send operation may be outstanding at a time for any TCP connections. Multiple sends /// may be in progress for UDP connections. /// </note> /// <note> /// For TCP connections, the send operation will continue until all bytes have been transmitted to the /// remote endpoint. For UDP connections, only a single packet with as many bytes as may be delivered /// by the underlying infrastructure will be send. /// </note> /// <note> /// All successful calls to <see cref="BeginSend" /> must eventually be followed by a call to <see cref="EndSend" />. /// </note> /// </remarks> public IAsyncResult BeginSend(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0 || count < 0 || offset + count > buffer.Length + 1) { throw new IndexOutOfRangeException(string.Format("[LiteSocket.Send: offset={0}] and [count={1}] is not valid for buffer of length [{2}].", offset, count, buffer.Length)); } lock (syncLock) { if (isTcp) { if (!Connected) { throw new InvalidOperationException("Socket is not connected."); } if (tcpSendPending) { throw new InvalidOperationException("LiteSocket.Send: Another send operation is already pending on this TCP socket."); } try { tcpSendPending = true; return(sock.BeginSend(buffer, offset, count, SocketFlags.None, callback, state)); } catch { tcpSendPending = false; throw; } } else { return(sock.BeginSendTo(buffer, offset, count, SocketFlags.None, udpRemoteEndPoint, callback, state)); } } }