?? network.cc
字號:
// network.cc // Routines to simulate a network interface, using UNIX sockets// to deliver packets between multiple invocations of nachos.//// DO NOT CHANGE -- part of the machine emulation//// Copyright (c) 1992-1996 The Regents of the University of California.// All rights reserved. See copyright.h for copyright notice and limitation // of liability and disclaimer of warranty provisions.#include "copyright.h"#include "network.h"#include "main.h"//-----------------------------------------------------------------------// NetworkInput::NetworkInput// Initialize the simulation for the network input//// "toCall" is the interrupt handler to call when packet arrives//-----------------------------------------------------------------------NetworkInput::NetworkInput(CallBackObj *toCall){ // set up the stuff to emulate asynchronous interrupts callWhenAvail = toCall; packetAvail = FALSE; inHdr.length = 0; sock = OpenSocket(); sprintf(sockName, "SOCKET_%d", kernel->hostName); AssignNameToSocket(sockName, sock); // Bind socket to a filename // in the current directory. // start polling for incoming packets kernel->interrupt->Schedule(this, NetworkTime, NetworkRecvInt);}//-----------------------------------------------------------------------// NetworkInput::NetworkInput// Deallocate the simulation for the network input// (basically, deallocate the input mailbox)//-----------------------------------------------------------------------NetworkInput::~NetworkInput(){ CloseSocket(sock); DeAssignNameToSocket(sockName);}//-----------------------------------------------------------------------// NetworkInput::CallBack// Simulator calls this when a packet may be available to// be read in from the simulated network.//// First check to make sure packet is available & there's space to// pull it in. Then invoke the "callBack" registered by whoever // wants the packet.//-----------------------------------------------------------------------voidNetworkInput::CallBack(){ // schedule the next time to poll for a packet kernel->interrupt->Schedule(this, NetworkTime, NetworkRecvInt); if (inHdr.length != 0) // do nothing if packet is already buffered return; if (!PollSocket(sock)) // do nothing if no packet to be read return; // otherwise, read packet in char *buffer = new char[MaxWireSize]; ReadFromSocket(sock, buffer, MaxWireSize); // divide packet into header and data inHdr = *(PacketHeader *)buffer; ASSERT((inHdr.to == kernel->hostName) && (inHdr.length <= MaxPacketSize)); bcopy(buffer + sizeof(PacketHeader), inbox, inHdr.length); delete [] buffer ; DEBUG(dbgNet, "Network received packet from " << inHdr.from << ", length " << inHdr.length); kernel->stats->numPacketsRecvd++; // tell post office that the packet has arrived callWhenAvail->CallBack();}//-----------------------------------------------------------------------// NetworkInput::Receive// Read a packet, if one is buffered//-----------------------------------------------------------------------PacketHeaderNetworkInput::Receive(char* data){ PacketHeader hdr = inHdr; inHdr.length = 0; if (hdr.length != 0) { bcopy(inbox, data, hdr.length); } return hdr;}//-----------------------------------------------------------------------// NetworkOutput::NetworkOutput// Initialize the simulation for sending network packets//// "reliability" says whether we drop packets to emulate unreliable links// "toCall" is the interrupt handler to call when next packet can be sent//-----------------------------------------------------------------------NetworkOutput::NetworkOutput(double reliability, CallBackObj *toCall){ if (reliability < 0) chanceToWork = 0; else if (reliability > 1) chanceToWork = 1; else chanceToWork = reliability; // set up the stuff to emulate asynchronous interrupts callWhenDone = toCall; sendBusy = FALSE; sock = OpenSocket();}//-----------------------------------------------------------------------// NetworkOutput::~NetworkOutput// Deallocate the simulation for sending network packets//-----------------------------------------------------------------------NetworkOutput::~NetworkOutput(){ CloseSocket(sock);}//-----------------------------------------------------------------------// NetworkOutput::CallBack// Called by simulator when another packet can be sent.//-----------------------------------------------------------------------voidNetworkOutput::CallBack(){ sendBusy = FALSE; kernel->stats->numPacketsSent++; callWhenDone->CallBack();}//-----------------------------------------------------------------------// NetworkOutput::Send// Send a packet into the simulated network, to the destination in hdr.// Concatenate hdr and data, and schedule an interrupt to tell the user // when the next packet can be sent //// Note we always pad out a packet to MaxWireSize before putting it into// the socket, because it's simpler at the receive end.//-----------------------------------------------------------------------voidNetworkOutput::Send(PacketHeader hdr, char* data){ char toName[32]; sprintf(toName, "SOCKET_%d", (int)hdr.to); ASSERT((sendBusy == FALSE) && (hdr.length > 0) && (hdr.length <= MaxPacketSize) && (hdr.from == kernel->hostName)); DEBUG(dbgNet, "Sending to addr " << hdr.to << ", length " << hdr.length); kernel->interrupt->Schedule(this, NetworkTime, NetworkSendInt); if (RandomNumber() % 100 >= chanceToWork * 100) { // emulate a lost packet DEBUG(dbgNet, "oops, lost it!"); return; } // concatenate hdr and data into a single buffer, and send it out char *buffer = new char[MaxWireSize]; *(PacketHeader *)buffer = hdr; bcopy(data, buffer + sizeof(PacketHeader), hdr.length); SendToSocket(sock, buffer, MaxWireSize, toName); delete [] buffer;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -