// PalvelinSaieEsimerkkiBinaari.java // Kuuntelee porttia, yhteydestä otta vastaan kokonaislukuja, vastaa neliöimällä // sulkee yhteyden jollei tule kokonaislukua // Säikeistettu versio // Esimerkki binääriprotokollasta import java.net.*; import java.lang.Thread; import java.io.DataOutputStream; import java.io.DataInputStream; import java.io.EOFException; import java.io.BufferedOutputStream; import java.io.BufferedInputStream; public class PalvelinSaieEsimerkkiBinaari { public static final int viestinPituus = 8; // int, int public static final int vastausViestinPituus = 12; // int, long // kuunteleva palvelintöpseli ServerSocket ss = null; public static void main(String[] args) { PalvelinSaieEsimerkkiBinaari p; if (args.length > 0) p = new PalvelinSaieEsimerkkiBinaari(Integer.valueOf(args[0])); else p = new PalvelinSaieEsimerkkiBinaari(); p.kuuntele(); } // main() // konstruktorit avaavat yhteyden kuuntelulle public PalvelinSaieEsimerkkiBinaari(int portti) { try { ss = new ServerSocket(portti); System.out.println("Kuunnellaan porttia " + portti); } catch (Exception e) { System.err.println(e); ss = null; } } public PalvelinSaieEsimerkkiBinaari() { this(1234); } // kuuntelu "säie" public void kuuntele() { try { while (true) { // odotetaan uutta yhteyttä Socket cs = ss.accept(); // luodaan ja käynnistetää uusi palvelijasäie new Palvelija(cs).start(); } } catch (Exception e) { System.err.println(e); ss = null; } } // kuuntele() // palvelee yhden yhteyden public class Palvelija extends Thread { Socket asiakas; public Palvelija(Socket cs) { super(); asiakas = cs; } public void run() { try { System.out.println("Uusi yhteys: " + asiakas.getInetAddress() + ":" + asiakas.getPort()); // virrat käyttökelpoiseen muotoon binääriprotokollalle DataOutputStream out = new DataOutputStream( new BufferedOutputStream(asiakas.getOutputStream())); DataInputStream in = new DataInputStream( new BufferedInputStream(asiakas.getInputStream())); // while-silmukasta poistutaan poikkeuksella kun asiakas sulkee yhteyden // tai break:lla jos viestin pituus < 8 while (true) { // luetaan viestin pituus (int32) int pituus = in.readInt(); if (pituus < viestinPituus) { // liian lyhyt viesti tulossa // katkaistaan yhteys break; } // luetaan itse data int data = in.readInt(); if (pituus > viestinPituus) { // ohitetaan loput tavut int skip = in.skipBytes(pituus - viestinPituus); if (skip != pituus - viestinPituus) { System.err.println("Pitkän viestin skippaus epäonnistyi"); break; } } // kirjoitetaan vastausviesti long vastaus = (long) data * data; out.writeInt(vastausViestinPituus); out.writeLong(vastaus); out.flush(); } // while asiakas.close(); } catch (EOFException eof) { // yhteys katkesi try { asiakas.close(); } catch (Exception e) { } asiakas = null; } catch (Exception e) { System.err.println(e); } } // run() } // class Palvelija } // class PalvelinSaieEsimerkkiBinaari