import java.io.*; import java.net.*; class Advertiser extends Thread { DatagramSocket as; DatagramPacket ad; Advertiser(DatagramSocket a, String msg, InetAddress dsaddr) { as=a; ad= new DatagramPacket(msg.getBytes(),msg.length(),dsaddr,8888); } public void run() { try { while (true) { as.send(ad); Thread.sleep(1000); } } catch(Exception e) { System.err.println("advertiser died: "+e); } } } class Worker extends Thread { Socket ts; String filename; Worker(Socket s,String n) { ts=s; filename=n; } public void run() { System.err.println("serving "+filename+" through "+ts); try { OutputStream out=ts.getOutputStream(); InputStream in=new FileInputStream(filename); int total=0; while (in.available()>0) { byte b[]=new byte[1024]; int len=in.read(b); out.write(b,0,len); out.flush(); total+=len; } out.close(); in.close(); System.err.println("done: "+total+" bytes transferred"); } catch (Exception any) { System.err.println("worker died "+any); System.exit(-1); } } } /** a thread that accepts new connections and fork off a worker for them */ class Welcomer extends Thread { ServerSocket ss; String fname; Welcomer(ServerSocket s,String fn) { ss=s; fname=fn; } public void run() { try { while(true) { Socket ts=ss.accept(); System.err.println("new client received on "+ss); Thread worker=new Worker(ts,fname); worker.start(); } } catch (Exception any) { System.err.println("welcomer died "+any); System.exit(-1); } } } class server { public static void main(String argv[]) throws Exception { if (argv.length<3) { System.err.println("usage : java server [morefiles]"); System.exit(-1); } int fileno=2; InetAddress dsaddr = InetAddress.getByName(argv[1]); String thisaddr = argv[0]; for (int port=8081;port<8100;port++) { String fname=argv[fileno]; /** when trying to bind the socket to a given port, java.net * will throw a SocketException if the port is already bound. */ try { ServerSocket listen=new ServerSocket(port); DatagramSocket advertise=new DatagramSocket(port); System.err.println("advertise to "+dsaddr+ ":8888, transfer over " +thisaddr+":"+port); String msg=thisaddr+":"+port+":"+fname+"\n"; /** nothing like a "check-if-accept-is-going-to-succeed" * in java.net, so we have to fork a thread for advertisements * and another thread that waits for incoming transmissions. */ Thread adv=new Advertiser(advertise,msg,dsaddr); adv.start(); Thread wlc=new Welcomer(listen,fname); wlc.start(); fileno++; if (fileno>=argv.length) { /** when all files have their advertiser/welcomer thread * spawn, we simply halt the 'root' thread by making it * join (i.e. wait for termination of) those threads. * program is interrupted with CTRL-C or on transfer * errors. */ adv.join(); wlc.join(); System.exit(0); } } catch (SocketException se) { System.err.println("port "+port+" failed ("+se+")"); } } } }