protected Queue <NetQItem> m_SendQueue = new Queue <NetQItem>(); // packet send queue /// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { SocketDebug(32); //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { Log.LogMsg("DuplexBlockingTransit - cant send data because owning connection isn't alive. MyTcpSocket == Null -> " + (OwningConnection.MyTCPSocket == null)); Log.LogMsg("Can't send on socket " + OwningConnection.MyTCPSocket.Handle.ToString() + " with socket error reading " + m_LastTCPReceiveStatus.ToString()); OwningConnection.KillConnection("Couldn't send. Connection has been closed."); return(-1); } SocketDebug(33); // Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; if (isUDP) { SocketDebug(34); if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return(0); } SocketDebug(35); // Don't allow fragmenting UDP packets if (data.Length > 1024) { Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } SocketDebug(36); NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; qi.IsUDP = isUDP; m_SendQueue.Enqueue(qi); Log.LogMsg("Send queue now has " + m_SendQueue.Count.ToString() + " items in it."); SocketDebug(37); return(1); } catch (Exception sendExc) { Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message); return(-1);; } return(1); }
protected Queue <NetQItem> m_SendQueue = new Queue <NetQItem>(); // packet send queue /// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { return(-1); } //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; if (isUDP) { if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return(0); } // Don't allow fragmenting UDP packets if (data.Length > 1024) { Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } lock (m_SendQueue) { NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; qi.IsUDP = isUDP; m_SendQueue.Enqueue(qi); Monitor.Pulse(m_SendQueue); return(1); } } catch (Exception sendExc) { return(-1);; } return(1); }
/// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { return -1; } //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; if (isUDP) { if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return 0; } // Don't allow fragmenting UDP packets if (data.Length > 1024) { Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } lock (m_SendQueue) { NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; qi.IsUDP = isUDP; m_SendQueue.Enqueue(qi); Monitor.Pulse(m_SendQueue); return 1; } } catch (Exception sendExc) { return -1; ; } return 1; }
/// <summary> /// Gets called when a send operation resolves. /// </summary> private void OnSendResolved(SocketAsyncEventArgs args, SockState state) { //// Log.LogMsg("Testy 13"); try { OwningConnection.SentBytes(state.PacketBufferPointer.Position); bool isUDP = (state.Flags & PacketFlags.UDP) != 0; //Log.LogMsg("==>#### Async SEND Op Completed - #" + ((SockState)args.UserToken).ID.ToString() + "#"); if (args.SocketError == SocketError.Success) { //// Log.LogMsg("Testy 14"); state.PacketBufferPointer.Advance(args.BytesTransferred); if (state.PacketBufferPointer.Position >= state.PacketBuffer.Length) { OwningConnection.PacketSent(); // Done sending packet. state.Reset(); //Log.LogMsg("==>Done sending packet. Sent " + state.PacketBufferPointer.Position.ToString() + " bytes."); // done sending packet, see if we have anything in the queue ready to go bool more = false; Queue <NetQItem> sendQ = isUDP ? m_SendQueueUDP : m_SendQueue; lock (sendQ) { if (sendQ.Count > 0) { NetQItem itm = sendQ.Dequeue(); state.PacketBuffer = itm.Data; state.Flags = itm.Flags; more = true; } else { // release the sending lock if (isUDP) { //Log.LogMsg("UDP send queue emptied."); Interlocked.Exchange(ref m_SendingUDP, 0); } else { //Log.LogMsg("TCP send queue emptied."); Interlocked.Exchange(ref m_Sending, 0); } } } if (more) { //// Log.LogMsg("Testy 15"); SendBuffer(args, state, isUDP); } return; } else { //// Log.LogMsg("Testy 16"); // not done sending. send again. //Log.LogMsg("==>Continuing send. " + state.PacketBufferPointer.Position.ToString() + " / " + state.PacketBuffer.Length.ToString() + " sent so far."); SendBuffer(args, state, isUDP); } } else { //If we are in this else-statement, there was a socket error. OwningConnection.KillConnection("Error sending packet. " + args.SocketError.ToString()); } } catch (Exception ex) { //// Log.LogMsg("Testy 17"); Log.LogMsg("Failed to ProcessSend. " + ex.Message); OwningConnection.KillConnection("Send error. " + ex.Message); } }
/// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { //// Log.LogMsg("Testy 3"); return(-1); } //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; #if SILVERLIGHT // Silverlight can't do UDP and it can only send Async, i.e. Non-Blocking isUDP = false; OwningConnection.BlockingMode = false; #endif if (isUDP) { //// Log.LogMsg("Testy 4"); if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return(0); } // Don't allow fragmenting UDP packets if (data.Length > m_SendArgsUDP.Buffer.Length && data.Length > 1024) { Log.LogMsg("Message exceeded UDP size. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } if (!OwningConnection.BlockingMode) { // send via asyncsend, but only one send op can be in progress at one time // out of order packets can happen because the actual send is done with I/O completion ports and if multiple // packets get submitted to the I/O queue they could be processed out of order, especially if the packet are of wildly differing sizes if (isUDP) { //// Log.LogMsg("Testy 5"); lock (m_SendQueueUDP) { if (1 == Interlocked.Exchange(ref m_SendingUDP, 1)) { // failed to get the lock - a message is in progress. queue message. NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; m_SendQueueUDP.Enqueue(qi); Log.LogMsg("Queueing UDP packet. Now " + m_SendQueueUDP.Count.ToString() + " in Queue."); return(1); } //Log.LogMsg("Acquired UDP send lock."); } } else { lock (m_SendQueue) { if (1 == Interlocked.Exchange(ref m_Sending, 1)) { // failed to get the lock - a message is in progress. queue message. NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; m_SendQueue.Enqueue(qi); Log.LogMsg("Queueing TCP packet. Now " + m_SendQueue.Count.ToString() + " in Queue."); return(1); } //Log.LogMsg("Acquired TCP send lock."); } } } SocketAsyncEventArgs args = isUDP ? m_SendArgsUDP : m_SendArgs; SockState state = args.UserToken as SockState; state.Flags = flags; state.PacketBuffer = data; //// Log.LogMsg("Testy 6"); SendBuffer(args, state, isUDP); } catch (Exception sendExc) { OwningConnection.KillConnection(sendExc.Message); return(-1);; } return(1); }
/// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { //// Log.LogMsg("Testy 3"); return -1; } //Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; #if SILVERLIGHT // Silverlight can't do UDP and it can only send Async, i.e. Non-Blocking isUDP = false; OwningConnection.BlockingMode = false; #endif if (isUDP) { //// Log.LogMsg("Testy 4"); if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return 0; } // Don't allow fragmenting UDP packets if (data.Length > m_SendArgsUDP.Buffer.Length && data.Length > 1024) { Log.LogMsg("Message exceeded UDP size. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } if (!OwningConnection.BlockingMode) { // send via asyncsend, but only one send op can be in progress at one time // out of order packets can happen because the actual send is done with I/O completion ports and if multiple // packets get submitted to the I/O queue they could be processed out of order, especially if the packet are of wildly differing sizes if (isUDP) { //// Log.LogMsg("Testy 5"); lock (m_SendQueueUDP) { if (1 == Interlocked.Exchange(ref m_SendingUDP, 1)) { // failed to get the lock - a message is in progress. queue message. NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; m_SendQueueUDP.Enqueue(qi); Log.LogMsg("Queueing UDP packet. Now " + m_SendQueueUDP.Count.ToString() + " in Queue."); return 1; } //Log.LogMsg("Acquired UDP send lock."); } } else { lock (m_SendQueue) { if (1 == Interlocked.Exchange(ref m_Sending, 1)) { // failed to get the lock - a message is in progress. queue message. NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; m_SendQueue.Enqueue(qi); Log.LogMsg("Queueing TCP packet. Now " + m_SendQueue.Count.ToString() + " in Queue."); return 1; } //Log.LogMsg("Acquired TCP send lock."); } } } SocketAsyncEventArgs args = isUDP ? m_SendArgsUDP : m_SendArgs; SockState state = args.UserToken as SockState; state.Flags = flags; state.PacketBuffer = data; //// Log.LogMsg("Testy 6"); SendBuffer(args, state, isUDP); } catch (Exception sendExc) { OwningConnection.KillConnection(sendExc.Message); return -1; ; } return 1; }
/// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { //Log.LogMsg("@__@ Monitor Enter"); if (!IsAlive) { KillConnection("Couldn't send. Connection has been closed."); return -1; } try { bool isUDP = (flags & PacketFlags.UDP) != 0; if (isUDP) { if (!CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return 0; } // Don't allow fragmenting UDP packets if (data.Length > 1024) { Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; qi.IsUDP = isUDP; m_SendQueue.Enqueue(qi); return 1; } catch (Exception sendExc) { Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message); return -1; ; } return 1; }
/// <summary> /// Sends arbitrary bytes of data across the wire. Note that if the remote endpoint can't decipher the data /// as a known packet, the connection will be dropped by that endpoint immediately. /// </summary> /// <param name="data">bytes to send</param> public virtual int Send(byte[] data, PacketFlags flags) { SocketDebug(32); //Log.LogMsg("@__@ Monitor Enter"); if (!OwningConnection.IsAlive) { Log.LogMsg("DuplexBlockingTransit - cant send data because owning connection isn't alive. MyTcpSocket == Null -> " + (OwningConnection.MyTCPSocket == null)); Log.LogMsg("Can't send on socket " + OwningConnection.MyTCPSocket.Handle.ToString() + " with socket error reading " + m_LastTCPReceiveStatus.ToString()); OwningConnection.KillConnection("Couldn't send. Connection has been closed."); return -1; } SocketDebug(33); // Log.LogMsg("==>Sending " + data.Length.ToString() + " bytes."); try { bool isUDP = (flags & PacketFlags.UDP) != 0; if (isUDP) { SocketDebug(34); if (!OwningConnection.CanSendUDP) { Log.LogMsg("!!! Tried sending UDP packet when the connection wasn't yet ready to send UDP. Dropping packet."); return 0; } SocketDebug(35); // Don't allow fragmenting UDP packets if (data.Length > 1024) { Log.LogMsg("Message exceeded UDP size of 1024 bytes. Sending via TCP instead."); flags &= ~PacketFlags.UDP; } } SocketDebug(36); NetQItem qi = new NetQItem(); qi.Flags = flags; qi.Data = data; qi.IsUDP = isUDP; m_SendQueue.Enqueue(qi); Log.LogMsg("Send queue now has " + m_SendQueue.Count.ToString() + " items in it."); SocketDebug(37); return 1; } catch (Exception sendExc) { Log.LogMsg("DuplexBlockingTransit - Failed to send data. " + sendExc.Message); return -1; ; } return 1; }