/// <summary> /// Called when a message has been successfully sent. /// /// Decodes the unsent bytes and tries sending them again. /// </summary> private void MessageSent(IAsyncResult result) { // Protect SendQueue lock (SendQueue) { try { // Find out how many bytes were actually sent int bytes = socket.EndSend(result); // Get the bytes that we attempted to send byte[] outgoingBuffer = (byte[])result.AsyncState; // If no bytes were received, close the socket. //if (bytes == 0) //{ // //what to do here??? // socket.Close(); //} // Prepend the unsent bytes and try sending again. //else { outgoing = encoding.GetString(outgoingBuffer, bytes, outgoingBuffer.Length - bytes) + outgoing; SendBytes(); } } catch (Exception e) { SendRequest sr2 = SendQueue.Dequeue(); ThreadPool.QueueUserWorkItem(x => sr2.sendCallback(e, sr2.payload)); } } }
/// <summary> /// Checks if the entire message has been sent. If the message hasn't been sent /// or there is another request, begin sending it. /// </summary> private void SendBytes() { if (SendQueue.Count > 0) { // If the entire message has been sent. if (outgoing == "") { // Dequeue the send request. SendRequest sr = SendQueue.Dequeue(); // Call the appropriate callback. ThreadPool.QueueUserWorkItem(x => sr.sendCallback(null, sr.payload)); // If there's another request in the queue, get its message and begin sending it. if (SendQueue.Count > 0) { outgoing = SendQueue.Peek().message; byte[] outgoingBuffer = encoding.GetBytes(outgoing); outgoing = ""; try { socket.BeginSend(outgoingBuffer, 0, outgoingBuffer.Length, SocketFlags.None, MessageSent, outgoingBuffer); } catch (Exception e) { SendRequest sr1 = SendQueue.Dequeue(); ThreadPool.QueueUserWorkItem(x => sr1.sendCallback(e, sr1.payload)); } } } // Otherwise, the entire message has not been sent. Send more. else { byte[] outgoingBuffer = encoding.GetBytes(outgoing); outgoing = ""; try { socket.BeginSend(outgoingBuffer, 0, outgoingBuffer.Length, SocketFlags.None, MessageSent, outgoingBuffer); } catch (Exception e) { SendRequest sr2 = SendQueue.Dequeue(); ThreadPool.QueueUserWorkItem(x => sr2.sendCallback(e, sr2.payload)); } } } }