⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 networklink.java

📁 Nachos 5 java version
💻 JAVA
字号:
// PART OF THE MACHINE SIMULATION. DO NOT CHANGE.package nachos.machine;import nachos.security.*;import java.io.IOException;import java.net.DatagramSocket;import java.net.DatagramPacket;import java.net.InetAddress;import java.net.UnknownHostException;import java.net.SocketException;/** * A full-duplex network link. Provides ordered, unreliable delivery of * limited-size packets to other machines on the network. Packets are * guaranteed to be uncorrupted as well. * * <p> * Recall the general layering of network protocols: * <ul> * <li>Session/Transport * <li>Network * <li>Link * <li>Physical * </ul> * * <p> * The physical layer provides a bit stream interface to the link layer. This * layer is very hardware-dependent. * * <p> * The link layer uses the physical layer to provide a packet interface to the * network layer. The link layer generally provides unreliable delivery of * limited-size packets, but guarantees that packets will not arrive out of * order. Some links protect against packet corruption as well. The ethernet * protocol is an example of a link layer. * * <p> * The network layer exists to connect multiple networks together into an * internet. The network layer provides globally unique addresses. Routers * (a.k.a. gateways) move packets across networks at this layer. The network * layer provides unordered, unreliable delivery of limited-size uncorrupted * packets to any machine on the same internet. The most commonly used network * layer protocol is IP (Internet Protocol), which is used to connect the * Internet. * * <p> * The session/transport layer provides a byte-stream interface to the * application. This means that the transport layer must deliver uncorrupted * bytes to the application, in the same order they were sent. Byte-streams * must be connected and disconnected, and exist between ports, not machines. * * <p> * This class provides a link layer abstraction. Since we do not allow * different Nachos networks to communicate with one another, there is no need * for a network layer in Nachos. This should simplify your design for the * session/transport layer, since you can assume packets never arrive out of * order. */public class NetworkLink {    /**     * Allocate a new network link.     *     * <p>     * <tt>nachos.conf</tt> specifies the reliability of the network. The     * reliability, between 0 and 1, is the probability that any particular     * packet will not get dropped by the network.     *     * @param	privilege      	encapsulates privileged access to the Nachos     * 				machine.     * @param	linkAddress	the address of this link.     */    public NetworkLink(Privilege privilege) {	System.out.print(" network");	this.privilege = privilege;	try {	    localHost = InetAddress.getLocalHost();	}	catch (UnknownHostException e) {	    localHost = null;	}	Lib.assert(localHost != null);	reliability = Config.getDouble("NetworkLink.reliability");	Lib.assert(reliability > 0 && reliability <= 1.0);	socket = null;	for (linkAddress=0;linkAddress<Packet.linkAddressLimit;linkAddress++) {	    try {		socket = new DatagramSocket(portBase + linkAddress, localHost);		break;	    }	    catch (SocketException e) {	    }	}	if (socket == null) {	    System.out.println("");	    System.out.println("Unable to acquire a link address!");	    Lib.assertNotReached();	}	System.out.print("(" + linkAddress + ")");	receiveInterrupt = new Runnable() {		public void run() { receiveInterrupt(); }	    };	sendInterrupt = new Runnable() {		public void run() { sendInterrupt(); }	    };				scheduleReceiveInterrupt();	Thread receiveThread = new Thread(new Runnable() {		public void run() { receiveLoop(); }	    });	receiveThread.start();    }    /**     * Returns the address of this network link.     *     * @return	the address of this network link.     */    public int getLinkAddress() {	return linkAddress;    }    /**     * Set this link's receive and send interrupt handlers.     *     * <p>     * The receive interrupt handler is called every time a packet arrives     * and can be read using <tt>receive()</tt>.     *     * <p>     * The send interrupt handler is called every time a packet sent with     * <tt>send()</tt> is finished being sent. This means that another     * packet can be sent.     *     * @param	receiveInterruptHandler	the callback to call when a packet     *					arrives.     * @param	sendInterruptHandler	the callback to call when another     *					packet can be sent.     */    public void setInterruptHandlers(Runnable receiveInterruptHandler,				     Runnable sendInterruptHandler) {	this.receiveInterruptHandler = receiveInterruptHandler;	this.sendInterruptHandler = sendInterruptHandler;    }    private void scheduleReceiveInterrupt() {	privilege.interrupt.schedule(Stats.NetworkTime, "network recv",				     receiveInterrupt);    }    private synchronized void receiveInterrupt() {	Lib.assert(incomingPacket == null);	if (incomingBytes != null) {	    try {		incomingPacket = new Packet(incomingBytes);		privilege.stats.numPacketsReceived++;	    }	    catch (MalformedPacketException e) {	    }	    incomingBytes = null;	    notify();	    if (incomingPacket == null)		scheduleReceiveInterrupt();	    else if (receiveInterruptHandler != null)		receiveInterruptHandler.run();	}	else {	    scheduleReceiveInterrupt();	}    }    /**     * Return the next packet received.     *     * @return	the next packet received, or <tt>null</tt> if no packet is     * 		available.     */    public Packet receive() {	Packet p = incomingPacket;		if (incomingPacket != null) {	    incomingPacket = null;	    scheduleReceiveInterrupt();	}	return p;    }    private void receiveLoop() {	while (true) {	    synchronized(this) {		while (incomingBytes != null) {		    try {			wait();		    }		    catch (InterruptedException e) {		    }		}	    }	    byte[] packetBytes;	    try {		byte[] buffer = new byte[Packet.maxPacketLength];		DatagramPacket dp = new DatagramPacket(buffer, buffer.length);				socket.receive(dp);		packetBytes = new byte[dp.getLength()];		System.arraycopy(buffer,0, packetBytes,0, packetBytes.length);	    }	    catch (IOException e) {		return;	    }	    synchronized(this) {		incomingBytes = packetBytes;	    }	}    }		        private void scheduleSendInterrupt() {	privilege.interrupt.schedule(Stats.NetworkTime, "network send",				     sendInterrupt);    }    private void sendInterrupt() {	Lib.assert(outgoingPacket != null);	// randomly drop packets, according to its reliability	if (Lib.random() <= reliability) {	    // ok, no drop	    privilege.doPrivileged(new Runnable() {		    public void run() { sendPacket(); }		});	}	else {	    outgoingPacket = null;	}	if (sendInterruptHandler != null)	    sendInterruptHandler.run();    }    private void sendPacket() {	Packet p = outgoingPacket;	outgoingPacket = null;		try {	    socket.send(new DatagramPacket(p.packetBytes, p.packetBytes.length,					   localHost, portBase+p.dstLink));	    privilege.stats.numPacketsSent++;	}	catch (IOException e) {	}    }    /**     * Send another packet. If a packet is already being sent, the result is     * not defined.     *     * @param	value	the packet to send.     */           public void send(Packet p) {	if (outgoingPacket == null)	    scheduleSendInterrupt();		outgoingPacket = p;    }    private static final int hash;    private static final short portBase;        /**     * The address of the network to which are attached all network links in     * this JVM. This is a hash on the account name of the JVM running this     * Nachos instance. It is used to help prevent packets from other users     * from accidentally interfering with this network.     */    public static final byte networkID;    static {	hash = System.getProperty("user.name").hashCode();	portBase = (short) (0x4E41 + Math.abs(hash%0x4E41));    	networkID  = (byte) (hash/0x4E41);	    }	    private Privilege privilege;    private Runnable receiveInterrupt;    private Runnable sendInterrupt;    private Runnable receiveInterruptHandler = null;    private Runnable sendInterruptHandler = null;    private InetAddress localHost;    private DatagramSocket socket;    private byte linkAddress;    private double reliability;    private byte[] incomingBytes = null;    private Packet incomingPacket = null;    private Packet outgoingPacket = null;    private boolean sendBusy = false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -