1. 程式人生 > >計算機網路課程大作業STEP1---Pinger

計算機網路課程大作業STEP1---Pinger

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Pinger {
	public static class UDPPacket{		
		int sequence_number;
		long timestamp;		
	}
	public static class UDPClient{
		int localport,remoteport,packetnum,seqnum,receivenum;
		long [] RTTs;
		InetAddress Serveraddress;
		DatagramSocket datagramSocket = null;
	    DatagramPacket datagramPacket = null;
	    
		public UDPClient(String remotehost, int lp, int rp, int pc)throws Exception{
			localport = lp;
			remoteport = rp;
			packetnum = pc;
			seqnum = 0;
			receivenum = 0;
			RTTs = new long[packetnum + 1];
			Serveraddress = InetAddress.getByName(remotehost);
			datagramSocket = new DatagramSocket(localport);
		}
		
		public void PingerClient(){
			try {
				for(int i = 1;i <= packetnum;i++) {
					UDPPacket send = new UDPPacket();
					send.sequence_number = seqnum ++ ;
					send.timestamp = System.currentTimeMillis();
					
					byte[] buf = new byte[12];
		            buf[0] = (byte)((send.timestamp >>> 0));			buf[1] = (byte)((send.timestamp >>> 8));
		            buf[2] = (byte)((send.timestamp >>> 16));			buf[3] = (byte)((send.timestamp >>> 24));
		            buf[4] = (byte)((send.timestamp >>> 32));			buf[5] = (byte)((send.timestamp >>> 40));
		            buf[6] = (byte)((send.timestamp >>> 48));			buf[7] = (byte)((send.timestamp >>> 56));
		            buf[8] =  (byte)((send.sequence_number >>> 0));		buf[9] =  (byte)((send.sequence_number >>> 8));
		            buf[10] = (byte)((send.sequence_number >>> 16));	buf[11] = (byte)((send.sequence_number >>> 24));
	
					datagramPacket = new DatagramPacket(buf, buf.length, Serveraddress, remoteport);
		            datagramSocket.send(datagramPacket);
	
					Thread t = new Thread(new Respond());
					t.start();
					Thread.sleep(1000);
				}
			}catch(Exception e) { e.printStackTrace(); }
			
			long max = 0,min = 1000000,sum = 0;
			for(int i = 1;i <= receivenum;i ++) {
				if(RTTs[i] > max) max = RTTs[i];
				if(RTTs[i] < min) min = RTTs[i];
				sum += RTTs[i];
			}
			System.out.print("sent=" + packetnum + '\t');
            System.out.print("receive=" + receivenum + '\t'); 
            System.out.print("lost=" + (double)(packetnum - receivenum) / (double)packetnum + '\t');  
            System.out.print("rtt min/avg/max = " + min + '/' + (double)sum/(double)receivenum + '/' + max + "ms\n");
		}
		class Respond implements Runnable {
			@Override
			public void run() {
				try {
				    UDPPacket receive = new UDPPacket(); 
			        byte[] receBuf = new byte[12];
			        DatagramPacket recePacket = new DatagramPacket(receBuf, receBuf.length);
			        datagramSocket.receive(recePacket);
			        long cur = System.currentTimeMillis();
			            
			        receive.sequence_number =  (int)receBuf[8];			receive.sequence_number += (int)receBuf[9] << 8;		
			        receive.sequence_number += (int)receBuf[10]<< 16;	receive.sequence_number += (int)receBuf[11]<< 32;
			        receive.timestamp =  (long)receBuf[0];				receive.timestamp += (long)receBuf[1] << 8;			
			        receive.timestamp += (long)receBuf[2] << 16;		receive.timestamp += (long)receBuf[3] << 24;			
			        receive.timestamp += (long)receBuf[4] << 32;		receive.timestamp += (long)receBuf[5] << 40;			
			        receive.timestamp += (long)receBuf[6] << 48;		receive.timestamp += (long)receBuf[7] << 56;

			        RTTs[++receivenum] = cur - receive.timestamp;
			        System.out.print("size = " + recePacket.getLength()  + '\t');
			        System.out.print("from = " + recePacket.getAddress() + '\t'); 
			        System.out.print("seq = "  + receive.sequence_number + '\t');  
			        System.out.print("rtt = "  + RTTs[receivenum]        + "ms\n");
				} 
			    catch (SocketException e) 		{e.printStackTrace();} 
			    catch (UnknownHostException e) 	{e.printStackTrace();} 
			    catch (IOException e) 			{e.printStackTrace();} 
			    //finally {if(datagramSocket != null) datagramSocket.close();}
			}
		}
	}
	public static class UDPServer{
		
		int localport;
		DatagramSocket datagramSocket = null;
	    DatagramPacket datagramPacket = null;
		
		public UDPServer(int lp) throws Exception{
			localport = lp;
			System.out.println("serving...");
			datagramSocket = new DatagramSocket(localport);
		}
		
		public void PingerServer() throws Exception {
		    
		    while(true) {
		    	byte[] receBuf = new byte[12];
		    	datagramPacket = new DatagramPacket(receBuf, receBuf.length);
		    	datagramSocket.receive(datagramPacket);
		    	Thread t = new Thread(new Respond(datagramPacket,receBuf));
				t.start();
		    }
		    
		}
		class Respond implements Runnable {
			DatagramPacket packet = null;
			byte[] info;
			
			Respond(DatagramPacket p,byte[] b){
				packet = p;
				info = b;
			}
			public void run(){
				try {	
					UDPPacket receive = new UDPPacket();
					long time = System.currentTimeMillis();
		            
		            receive.sequence_number =  (int)info[8];		receive.sequence_number += (int)info[9] << 8;		
		            receive.sequence_number += (int)info[10]<< 16;	receive.sequence_number += (int)info[11]<< 24;
		            receive.timestamp =  (long)info[0];				receive.timestamp += (long)info[1] << 8;			
		            receive.timestamp += (long)info[2] << 16;		receive.timestamp += (long)info[3] << 24;			
		            receive.timestamp += (long)info[4] << 32;		receive.timestamp += (long)info[5] << 40;			
		            receive.timestamp += (long)info[6] << 48;		receive.timestamp += (long)info[7] << 56;
		            
		            System.out.print("time = " + time + '\t');
		            System.out.print("from = " + packet.getAddress() + '\t'); 
		            System.out.print("seq = " + receive.sequence_number + '\n');  
		           
		            DatagramPacket recePacket = new DatagramPacket(info,info.length,packet.getAddress(),packet.getPort());
		            datagramSocket.send(recePacket);
		        } 
				catch (SocketException e) 	{e.printStackTrace();} 
				catch (IOException e) 		{e.printStackTrace();} 
				//finally {if(datagramSocket != null) datagramSocket.close();}
			}
		}
	}
	public static void main(String []args){
		
		boolean mode;//1 is Server mode and 0 is Client mode
		
		if( (args.length >= 2) && (args[0].equals("-l")) ) {
			if( (args.length == 2) ) mode = true;
			else if ((args.length == 8) && (args[2].equals("-h")) && (args[4].equals("-r")) && (args[6].equals("-c"))) 
				mode = false;
			else {
				System.out.println("Error: wrong arguments");
				return;
			}
		}
		else {
			System.out.println("Error: missing or additional arguments");
			return;
		}
	
		if(mode) {
			System.out.println("Server mode.");
			UDPServer server = null;
			try {server = new UDPServer(Integer.parseInt(args[1]));} 
			catch (NumberFormatException e1) 	{e1.printStackTrace();} 
			catch (Exception e1) 				{e1.printStackTrace();}
			try {server.PingerServer();} 
			catch (Exception e) 				{e.printStackTrace();}
		}
		else {
			System.out.println("Client mode.");
			UDPClient client = null;
			try {client = new UDPClient(args[3],Integer.parseInt(args[1]),Integer.parseInt(args[5]),Integer.parseInt(args[7]));} 
			catch (NumberFormatException e) 	{e.printStackTrace();} 
			catch (Exception e) 				{e.printStackTrace();}
			client.PingerClient();
		}
	}

}