protected int write(ByteBuffer buffer) { int byteSendSum = 0; beforeSend(buffer); while (buffer.HasRemaining) { int byteSent = mInnerChannel.Write(buffer); byteSendSum += byteSent; if (byteSent == 0) { break; } } return(byteSendSum); }
private void processACK(TCB tcb, TCPHeader tcpHeader, ByteBuffer payloadBuffer, ByteBuffer responseBuffer) { try { int payloadSize = payloadBuffer.Limit() - payloadBuffer.Position(); lock (tcb) { SocketChannel outputChannel = tcb.channel; if (tcb.status == TCB.TCBStatus.SYN_RECEIVED) { tcb.status = TCB.TCBStatus.ESTABLISHED; selector.Wakeup(); tcb.selectionKey = outputChannel.Register(selector, SelectionKey.OpRead, tcb); tcb.waitingForNetworkData = true; } else if (tcb.status == TCB.TCBStatus.LAST_ACK) { CloseCleanly(tcb, responseBuffer); return; } if (payloadSize == 0) { return; // Empty ACK, ignore } if (!tcb.waitingForNetworkData) { selector.Wakeup(); // tcb.selectionKey.InterestOps(SelectionKey.OpRead); tcb.selectionKey.InterestOps(); tcb.waitingForNetworkData = true; } // Forward to remote server try { while (payloadBuffer.HasRemaining) { outputChannel.Write(payloadBuffer); } } catch (IOException e) { Log.Error(TAG, "Network write error: " + tcb.ipAndPort, e); SendRST(tcb, payloadSize, responseBuffer); return; } // TODO: We don't expect out-of-order packets, but verify tcb.myAcknowledgementNum = tcpHeader.sequenceNumber + payloadSize; tcb.theirAcknowledgementNum = tcpHeader.acknowledgementNumber; Packet referencePacket = tcb.referencePacket; referencePacket.updateTCPBuffer(responseBuffer, (byte)TCPHeader.ACK, tcb.mySequenceNum, tcb.myAcknowledgementNum, 0); } outputQueue.Offer(responseBuffer); } catch (Exception ex) { System.Console.WriteLine(ex.Message); } }