Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
NetAdapterCx-clientstuurprogramma's ontvangen netwerkgegevens wanneer het framework hun EvtPacketQueueAdvance-callbackfunctie voor een ontvangstwachtrij aanroept. Tijdens deze callback geven client-stuurprogramma's aan dat er iets ontvangen is door ontvangen fragmenten en pakketten naar het besturingssysteem leeg te maken en vervolgens nieuwe buffers beschikbaar te stellen op de hardware.
Overzicht van ontvangen (Rx) post- en afvoerbewerkingen
In de volgende animatie ziet u hoe een clientstuurprogramma voor een eenvoudige PCI-netwerkinterfacekaart (NIC) post- en afvoerbewerkingen uitvoert voor een ontvangstwachtrij (Rx). Fragmentbuffers in dit voorbeeldscenario worden toegewezen en gekoppeld aan de fragmentring door het besturingssysteem. In dit voorbeeld wordt ervan uitgegaan dat er een een-op-een-relatie bestaat tussen de hardware-ontvangstwachtrij en de besturingssysteemontvangstwachtrij.
In deze animatie worden de pakketten die eigendom zijn van het clientstuurprogramma gemarkeerd in lichtblauw en donkerblauw, en fragmenten die eigendom zijn van het clientstuurprogramma zijn gemarkeerd in geel en oranje. De lichtere kleuren vertegenwoordigen de afvoer subsectie van de elementen waarvan de bestuurder eigenaar is, terwijl de donkerdere kleuren de post subsectie van de elementen vertegenwoordigen waarvan de bestuurder eigenaar is.
Gegevens op volgorde ontvangen
Hier volgt een typische volgorde voor een stuurprogramma dat gegevens op volgorde ontvangt, met één fragment per pakket.
- Roep NetRxQueueGetRingCollection aan om de ringverzamelingsstructuur van de ontvangstwachtrij op te halen. U kunt dit opslaan in de contextruimte van de wachtrij om het aantal oproepen vanuit de stuurprogramma te verminderen. Gebruik de ringverzameling om de iterator voor het legen van de fragmentring en pakketring van de ontvangstwachtrij op te halen.
- Geef ontvangen gegevens aan het besturingssysteem aan door de net-ringen leeg te maken:
- Wijs UINT32-variabelen toe voor het bijhouden van de huidige index van de fragmentring en de huidige index van de pakketring. Stel deze variabelen in op de BeginIndex van hun respectieve net-ringen, wat het begin is van de afvoersubsectie van de ring. Wijs een UINT32-variabele toe voor het einde van de afvoersectie van de fragmentring door deze in te stellen op de NextIndex van de fragmentring.
- Ga als volgt te werk in een lus:
- Controleer of het fragment is ontvangen door de hardware. Als dat niet zo is, verlaat u de lus.
- Roep NetRingGetFragmentAtIndex aan om een fragment op te halen.
- Vul de gegevens van het fragment in, zoals validLength, op basis van de overeenkomende hardwaredescriptor.
- Haal een pakket voor dit fragment op door NetRingGetPacketAtIndex aan te roepen.
- Bind het fragment aan het pakket door fragmentIndex van het pakket in te stellen op de huidige index van het fragment in de fragmentring en het aantal fragmenten op de juiste manier in te stellen (in dit voorbeeld is het ingesteld op 1).
- U kunt eventueel andere pakketgegevens invullen, zoals controlesomgegevens.
- Verhoog de fragmentindex door NetRingIncrementIndexaan te roepen.
- Vergroot de pakketindex door NetRingIncrementIndexaan te roepen.
- Werk de BeginIndex van de fragmentring bij naar de huidige indexvariabele voor fragmenten en werk de BeginIndex van de pakketring bij naar de huidige pakketindex om het aangeven van ontvangen pakketten en hun fragmenten aan het besturingssysteem te voltooien.
- Post fragmentbuffers naar hardware voor de volgende ontvangsten:
- Stel de huidige fragmentindex in op de NextIndex van de fragmentring. Dit is het begin van de postsubsectie van de ring. Stel de eindindex van het fragment in op de EndIndex van de fragmentring.
- Ga als volgt te werk in een lus:
- Plaats de informatie van het fragment op de overeenkomende hardwaredescriptor.
- Verhoog de fragmentindex door NetRingIncrementIndexaan te roepen.
- Werk de NextIndex van de fragmentring bij naar de huidige indexvariabele voor fragmenten om het posten van fragmenten op hardware te voltooien.
Deze stappen kunnen er als volgt uitzien in de code:
void
MyEvtRxQueueAdvance(
NETPACKETQUEUE RxQueue
)
{
//
// Retrieve the receive queue's ring collection and net rings.
// This example stores the Rx queue's ring collection in its queue context space.
//
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 = 0;
UINT32 currentFragmentIndex = 0;
UINT32 fragmentEndIndex = 0;
//
// Indicate receives by draining the rings
//
currentPacketIndex = packetRing->BeginIndex;
currentFragmentIndex = fragmentRing->BeginIndex;
fragmentEndIndex = fragmentRing->NextIndex;
while(currentFragmentIndex != fragmentEndIndex)
{
// Test for fragment reception. Break if fragment has not been received.
...
//
NET_FRAGMENT * fragment = NetRingGetFragmentAtIndex(fragmentRing, currentFragmentIndex);
fragment->ValidLength = ... ;
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->FragmentIndex = currentFragmentIndex;
packet->FragmentCount = 1;
if(rxQueueContext->IsChecksumExtensionEnabled)
{
// Fill in checksum info
...
//
}
currentFragmentIndex = NetRingIncrementIndex(fragmentRing, currentFragmentIndex);
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
fragmentRing->BeginIndex = currentFragmentIndex;
packetRing->BeginIndex = currentPacketIndex;
//
// Post fragment buffers to hardware
//
currentFragmentIndex = fragmentRing->NextIndex;
fragmentEndIndex = fragmentRing->EndIndex;
while(currentFragmentIndex != fragmentEndIndex)
{
// Post fragment information to hardware descriptor
...
//
currentFragmentIndex = NetRingIncrementIndex(fragmentRing, currentFragmentIndex);
}
fragmentRing->NextIndex = currentFragmentIndex;
}
Gegevens buiten de volgorde ontvangen
In tegenstelling tot een Tx-wachtrij ontvangen clientstuurprogramma's doorgaans geen gegevens in de juiste volgorde als ze één wachtrij voor het ontvangen van het besturingssysteem per hardwarewachtrij hebben. Dit is ongeacht het type NIC van de client. Of het apparaat is gebaseerd op PCI en het besturingssysteem de ontvangstbuffers toewijst en eigenaar is van de ontvangstbuffers, of het apparaat usb-gebaseerd is en de USB-stack eigenaar is van de ontvangstbuffers, het clientstuurprogramma initialiseert een pakket voor elk ontvangen fragment en geeft dit aan aan het besturingssysteem. De volgorde is in dit geval niet belangrijk.
Als uw hardware meer dan één wachtrij voor het ontvangen van het besturingssysteem per hardware-ontvangstwachtrij ondersteunt, moet u de toegang tot de ontvangstbuffers synchroniseren. Het bereik hiervan valt buiten dit onderwerp en is afhankelijk van het ontwerp van uw hardware.