Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Sterowniki klienta NetAdapterCx anulują dane sieciowe, gdy platforma wywołuje funkcję zwrotną ich EvtPacketQueueCancel dla kolejki pakietów. To wywołanie zwrotne polega na tym, że sterowniki klienta wykonują wszelkie wymagane operacje przetwarzania, zanim platforma usunie kolejki pakietów.
Anulowanie kolejki transmisji
W funkcji zwrotnej EvtPacketQueueCancel dla kolejki transmisji masz możliwość ukończenia wszystkich zaległych pakietów transmisji. W przeciwieństwie do kolejki odbierania, nie jesteś do tego zobowiązany. Jeśli pozostawisz zaległe pakiety, NetAdapterCx wywołuje EvtPacketQueueAdvance dla kolejki transmisji, gdzie przetwarzasz je w ramach zwykłej operacji.
Jeśli sprzęt obsługuje anulowanie transmisji w locie, należy również przesunąć iterator pakietów pierścienia sieciowego poza wszystkie anulowane pakiety. Może to wyglądać podobnie do następującego przykładu:
void
MyEvtTxQueueCancel(
NETPACKETQUEUE TxQueue
)
{
// Get the transmit queue's context to retrieve the net ring collection
PMY_TX_QUEUE_CONTEXT txQueueContext = MyGetTxQueueContext(TxQueue);
NET_RING_COLLECTION const * ringCollection = txQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
while (currentPacketIndex != packetEndIndex)
{
// Mark this packet as canceled with the scratch field, then move past it
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Scratch = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
}
Jeśli sprzęt nie obsługuje anulowania, to wywołanie zwrotne może zakończyć się bez żadnej reakcji.
Anulowanie kolejki odbierania
W EvtPacketQueueCancel funkcji wywołania zwrotnego dla kolejki odbierania należy ukończyć wszystkie zaległe pakiety odbioru. Jeśli nie zwrócisz wszystkich pakietów, system operacyjny nie usunie kolejki, a program NetAdapterCx przestanie wywoływać wywołania zwrotne dla kolejki.
Aby zwrócić pakiety, należy najpierw spróbować wskazać wszystkie odebrane pakiety, które mogły zostać wykazane podczas wyłączania ścieżki odbierania, a następnie ustawić wszystkie pakiety do zignorowania i zwrócić do systemu operacyjnego wszystkie fragmenty. Może to wyglądać podobnie do poniższego przykładu kodu.
Notatka
W tym przykładzie pomijane są szczegóły wskazujące na otrzymywanie. Aby zapoznać się z przykładem kodu odbierającego dane, zobacz Odbieranie danych sieciowych za pomocą pierścieni sieciowych.
void
MyEvtRxQueueCancel(
NETPACKETQUEUE RxQueue
)
{
// Get the receive queue's context to retrieve the net ring collection
PMY_RX_QUEUE_CONTEXT rxQueueContext = MyGetRxQueueContext(RxQueue);
NET_RING_COLLECTION const * ringCollection = rxQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
NET_RING * fragmentRing = ringCollection->Rings[NET_RING_TYPE_FRAGMENT];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
// Set hardware register for cancellation
...
//
// Indicate receives
...
//
// Get all packets and mark them for ignoring
currentPacketIndex = packetRing->BeginIndex;
while(currentPacketIndex != packetEndIndex)
{
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Ignore = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
// Return all fragments to the OS
fragmentRing->BeginIndex = fragmentRing->EndIndex;
}