- package robot;
- import java.io.*;
- import java.net.*;
- import java.util.*;
- /**
- *
- * @author Tomas Zeidler
- * @author zeidltom@fel.cvut.cz
- */
- class Robot {
- public static void main(String[] args) throws SocketException, UnknownHostException, FileNotFoundException, IOException {
- if (args.length == 0) {
- System.err.println("Client: java robot.Robot <hostname> <port>");
- System.err.println("Server: java robot.Robot <port>");
- System.exit(1);
- } else if (args.length > 1) {
- } else {
- System.out.println("Spousteni DOWNLOADU...\n");
- Download download = new Download(args[0], 4000);
- //Download download = new Download("baryk.fit.cvut.cz", 4000);
- download.startDownload();
- }
- }
- }
- class Download { //trida starajici se o pripojeni a stazeni fotky
- public InetAddress address;
- public DatagramSocket dsocket;
- private byte[] databyte;
- private int id;
- private int lengthInPacket;
- Download(String string, int i) throws SocketException, UnknownHostException {
- address = InetAddress.getByName(string);
- dsocket = new DatagramSocket(i);
- dsocket.connect(address, 4000);
- dsocket.setSoTimeout(100);
- databyte = new byte[250000];
- /*for (int j = 0; j < 250000; j++) {
- databyte[j] = 0;
- }*/
- }
- void startDownload() throws SocketException, FileNotFoundException, IOException { //hlavni metoda starajici se o komunikaci
- byte[] uvodniData = new byte[1];
- uvodniData[0] = 1;
- Packet uvodniPacket = new Packet(0, 0, 0, 1, uvodniData); //vytvoreni a odeslani SYN packetu
- odeslatPacket(uvodniPacket);
- id = -1;
- Packet p;
- while (true) { //cekani na prijem SYN packetu
- try {
- p = prijmoutPacket();
- if (p.flags == 1) {
- this.id = p.id;
- break;
- }
- } catch (SocketTimeoutException ex) {
- System.err.println(ex.getMessage());
- odeslatPacket(uvodniPacket);
- }
- }
- System.out.println("Moje ID: " + Integer.toHexString(this.id));
- Packet rec;
- int main = 0;
- int temp = 0;
- int last = 0;
- int preteceni = 0;
- dsocket.setSoTimeout(2000);
- while (true) { //zpracovani prijateho packetu
- try {
- rec = prijmoutPacket();
- if (rec.id == this.id) { //kontrola ID
- System.out.println(lengthInPacket);
- if (rec.flags == 0) { //kontrola flags pro normalni komunikaci
- for (int i = 0; i < 260; i++) { //kontrola preteceni
- if (i * 255 + 254 == rec.seq) {
- preteceni = 1;
- System.out.println("preteceni1");
- break;
- }
- if (i * 255 + 253 == rec.seq) {
- preteceni = 2;
- System.out.println("preteceni2");
- break;
- }
- if (i * 255 + 252 == rec.seq) {
- preteceni = 3;
- System.out.println("preteceni3");
- break;
- }
- if (i * 255 + 255 == rec.seq) {
- preteceni = 0;
- System.out.println("preteceni0");
- break;
- }
- }
- if (rec.seq == main * 255) { //ulozeni dat z packetu do pole bytu
- System.arraycopy(rec.data, 0, databyte, rec.seq, rec.data.length);
- main++;
- } else {
- System.arraycopy(rec.data, 0, databyte, rec.seq + preteceni * 65536, rec.data.length);
- }
- if (lengthInPacket < 255) { //kontrola posledniho packetu
- last = lengthInPacket + rec.seq;
- if (((main + temp) * 255) % 65536 >= rec.seq) {
- Packet konecnyPacket = new Packet(this.id, 0, last, 0, new byte[0]);
- odeslatPacket(konecnyPacket);
- continue;
- }
- }
- temp = 0;
- if (databyte[main * 255] == 0 && databyte[main * 255 + 1] == 0) { //kontrola pro odeslani ack
- System.out.println("-----------------------------------------------------------------------1");
- Packet potvrzovaciPacket = new Packet(this.id, 0, main * 255 % 65536, 0, new byte[0]);
- odeslatPacket(potvrzovaciPacket);
- } else {
- while (databyte[(main + temp) * 255] != 0 || databyte[(main + temp) * 255 + 10] != 0 || databyte[(main + temp) * 255 + 20] != 0 || databyte[(main + temp) * 255 + 30] != 0) {
- temp++;
- }
- System.out.println(databyte[(main + temp) * 255] + " " + databyte[(main + temp) * 255 + 10] + " " + databyte[(main + temp) * 255 + 20] + " " + databyte[(main + temp) * 255 + 30]);
- System.out.println("-------------------------------------------------------------------2---" + (main + temp));
- Packet potvrzovaciPacket = new Packet(this.id, 0, ((main + temp) * 255) % 65536, 0, new byte[0]);
- odeslatPacket(potvrzovaciPacket);
- }
- } else if (rec.flags == 1) { //kontrola flags pro SYN
- System.err.println("===== CHYBA prijem SYN =====");
- } else if (rec.flags == 2) { //kontrola flags pro FIN
- System.out.println("========== Prijat FIN, odesilam FIN ==========");
- byte[] finData = new byte[0];
- Packet finPacket = new Packet(this.id, 0, rec.seq, 2, finData);
- odeslatPacket(finPacket);
- break;
- } else if (rec.flags == 4) { //kontrola flags pro RST
- System.out.println("===== VAROVANI prijem RST =====");
- } else { //pokud prijde uplne jine flags
- System.out.println("===== CHYBA prijem ??? =====");
- }
- } else { //pokud prijde spatne ID
- System.out.println("VAROVANI spatne ID");
- }
- } catch (Exception ex) {
- System.err.println(ex);
- break;
- }
- }
- writeFile(databyte, "foto_" + new Date().getTime() + ".png", last);
- System.out.println("Done");
- close();
- }
- public void writeFile(byte[] bytes, String fileName, int last) throws FileNotFoundException, IOException { //zapis pole bytu do souboru
- byte[] out = new byte[196608 + last];
- System.arraycopy(bytes, 0, out, 0, 196608 + last);
- FileInputStream fileInputStream = null;
- File file = new File(fileName);
- if (file.exists()) {
- file.delete();
- }
- file.createNewFile();
- fileInputStream = new FileInputStream(file);
- fileInputStream.read(out);
- fileInputStream.close();
- FileOutputStream fileOuputStream = new FileOutputStream(fileName);
- fileOuputStream.write(out);
- fileOuputStream.close();
- }
- public void odeslatPacket(Packet packet) { //odesila packet
- try {
- DatagramPacket dp = new DatagramPacket(packet.getPacket(), packet.getSize());
- dsocket.send(dp);
- int lengthOutPacket = packet.getSize() - 9;
- System.out.println("Odeslan: id=" + Integer.toHexString(packet.id) + " ack=" + packet.ack + " flags=" + packet.flags + " o velikosti " + lengthOutPacket);
- } catch (IOException ex) {
- System.err.println("CHYBA odeslatPacket " + ex);
- }
- }
- public Packet prijmoutPacket() throws SocketTimeoutException { //prijima packet
- byte[] prijataData = new byte[264];
- DatagramPacket dp = new DatagramPacket(prijataData, 264);
- try {
- dsocket.receive(dp);
- } catch (SocketTimeoutException ex) {
- throw new SocketTimeoutException("CHYBA prijmoutPacket " + ex.getMessage());
- } catch (Exception e) {
- System.err.println("CHYBA 2 prijmoutPacket " + e.getMessage());
- }
- Packet packet = new Packet(prijataData);
- lengthInPacket = dp.getLength() - 9;
- System.out.println("Prijat: id=" + Integer.toHexString(packet.id) + " seq=" + packet.seq + " flags=" + packet.flags + " o velikosti " + lengthInPacket);
- return packet;
- }
- public void close() { //uzavre DatagramSocket
- dsocket.close();
- }
- }
- class Packet { //trida pro praci s packetem
- public int id;
- public int seq;
- public int ack;
- public int flags;
- public byte[] data;
- public Packet(int id, int seq, int ack, int flags, byte[] data) { //kostruktor - pro vytvoreni packetu z dat
- this.id = id;
- this.seq = seq;
- this.ack = ack;
- this.flags = flags;
- if (data == null) {
- this.data = new byte[0];
- } else {
- this.data = data;
- }
- }
- public Packet(byte[] pole) { // konstruktor - zjisti z pole bytu id, seq, ack, flags a data
- this.data = new byte[pole.length - 9];
- this.id = (byteToInt(pole[0]) << 24) + (byteToInt(pole[1]) << 16) + (byteToInt(pole[2]) << 8) + byteToInt(pole[3]);
- this.seq = (byteToInt(pole[4]) << 8) + byteToInt(pole[5]);
- this.ack = (byteToInt(pole[6]) << 8) + byteToInt(pole[7]);
- this.flags = byteToInt(pole[8]);
- for (int i = 0; i < pole.length - 9; i++) {
- this.data[i] = pole[i + 9];
- }
- }
- public int getSize() { //vrati velikost packetu
- return 9 + data.length;
- }
- public byte[] getPacket() { //vztvori a vrati packet
- byte[] out = new byte[264];
- out[0] = (byte) ((id >> 24) % 256);
- out[1] = (byte) ((id >> 16) % 256);
- out[2] = (byte) ((id >> 8) % 256);
- out[3] = (byte) ((id) % 256);
- out[4] = (byte) ((seq >> 8) % 256);
- out[5] = (byte) ((seq) % 256);
- out[6] = (byte) ((ack >> 8) % 256);
- out[7] = (byte) ((ack) % 256);
- out[8] = (byte) ((flags));
- System.arraycopy(data, 0, out, 9, data.length);
- return out;
- }
- private int byteToInt(byte b) { //prevede bytovou hodnotu do int
- return (int) ((b < 0) ? (b + 256) : b);
- }
- }