2017-06-20 8 views
-2

少し大学のプロジェクト私はサーバーとクライアントのUDP communitcationをコードする必要があります。JavaクライアントサーバーUDPが間違ったパッケージを取得しています

クライアントがデータを送信し、サーバーが読み取るだけの場合はすべて正常です。私がサーバからクライアントにデータを送るとすぐに私の小さなプログラムのバグ。

public class Sensors { 
private static List<Produkt> allSensors = new ArrayList<Produkt>(); 

public static void main(String[] args) throws Exception { 
    //Preparing Our Data 
    initSensors(); 
    //Server Config 
    String serverIP = new String(); 
    BufferedReader eingabe = new BufferedReader(new InputStreamReader(System.in)); 
    System.out.print("IP Eintragen:"); 
    serverIP = eingabe.readLine(); 
    System.out.println(""); 

    //Preparing Data to Send 

    try{ 
     DatagramSocket serverSocket = new DatagramSocket(1234); 
     byte[] receiveData = new byte[4]; 
     DatagramPacket receivePacket = new DatagramPacket(receiveData, 
         receiveData.length); 

     for(;;){ 

      //Sending 
      for (Produkt s : allSensors) { 
       ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
       ObjectOutputStream os = new ObjectOutputStream(outputStream); 
       os.writeObject(s); 
       byte[] sendData = outputStream.toByteArray(); 
       InetAddress ia = InetAddress.getByName(serverIP); 
       DatagramPacket sendPacket= new DatagramPacket(sendData,sendData.length,ia,1223); 
       serverSocket.send(sendPacket); 
       outputStream.close(); 
      } 
      for (Produkt s : allSensors) { 
       System.out.println(s); 
      } 
      //Empfangen 
      try{ 
      serverSocket.receive(receivePacket); 
      String sentence = new String(receivePacket.getData(), 0, 
          receivePacket.getLength()); 
      System.out.println("RECEIVED: " + sentence); 

      }catch(IOException e){ 

      } 
      Thread.sleep(1000); 
      reduceValue(); 
     } 

    }catch (IOException e) { 
      System.out.println(e); 
    } 



} 

static public void initSensors() { 

    allSensors.add(new Produkt("Äpfel", 0, 100, "")); 
    allSensors.add(new Produkt("Birnen", 0, 100, "")); 
    allSensors.add(new Produkt("Kiwis", 0, 100, "")); 
    allSensors.add(new Produkt("Bananen", 0, 100, "")); 
    for (Produkt s : allSensors) { 
     System.out.print(s.p_name + " : " + s.p_quant + "\n"); 
    } 
} 

static public void reduceValue() { 
    for (Produkt s : allSensors) { 
     if (s.p_quant > 0) { 
      s.p_quant -= 20; 
     } 
    } 

} 

static public void fillValue() { 
    for (Produkt s : allSensors) { 
     s.p_quant = 100; 
    } 
} 

}

public class Fridge extends Thread { 

private static int port; 
private static String htmlInsert = ""; 
private static DataShare ds; 

public Fridge(int port, DataShare ds) { 
    this.port = port; 
    this.ds = ds; 
} 

@Override 
public void run() { 

    System.out.println("Start Fridge Server"); 

    try { 
     handleRequest(); 
    } catch (Exception ex) { 
     Logger.getLogger(Fridge.class.getName()).log(Level.SEVERE, null, ex); 
    } 

} 

static public void handleRequest() throws Exception { 
    try{ 
     DatagramSocket serverSocket = new DatagramSocket(port); 
     byte[] recivingData = new byte[512]; 

     DatagramPacket receivePacket = new DatagramPacket(recivingData, recivingData.length); 


     for(;;) 
     { 
      if(!ds.produkte.isEmpty()){ 
       if(ds.produkte.get(0).p_quant == 0){ 
        ds.reOrder = true; 
       }else{ 
        ds.reOrder = false; 
       } 
      } 
      //Empfangen 
      serverSocket.receive(receivePacket); 
      //prepare Data for conversion into Produkt 
      recivingData = receivePacket.getData(); 
      ByteArrayInputStream in = new ByteArrayInputStream(recivingData); 
      ObjectInputStream is = new ObjectInputStream(in); 
      Produkt reveivedProdukt = (Produkt) is.readObject(); 
      //Decoding Produkt into DataShare 
      //System.out.println(reveivedProdukt); 
      decodeData(reveivedProdukt); 
      writeHTML(); 

      //Senden 
      String reorder = new String(); 
      if(ds.reOrder){ 
       reorder = "FILL"; 
      }else{ 
       reorder ="NOT"; 
      } 
      System.out.println(reorder); 
      byte[] sendingDate = reorder.getBytes("UTF-8"); 
      DatagramPacket sendingPacket = new DatagramPacket(sendingDate, sendingDate.length, 
        receivePacket.getAddress(),receivePacket.getPort()); 
      serverSocket.send(sendingPacket); 

     } 

    }catch(IOException e){ 
     System.out.println(e); 
    }catch(ClassNotFoundException e){ 
     e.printStackTrace(); 
    } 


} 

static public void writeHTML() throws Exception { 
    List<String> lines = new ArrayList<String>(Arrays.asList("<!DOCTYPE html>\n", 
      "<html>\n", 
      " <head>\n", 
      "  <meta charset=\"utf-8\">\n", 
      "  <title>Test</title>\n", 
      " </head>\n", 
      " <body>\n", 
      "\n", 
      "  <h1 style=\"color:red;\">Das ist ein Test</h1>\n", 
      "\n", 
      " </body>\n", 
      "</html>")); 
    htmlInsert += "<p>"; 
    for(Produkt p : ds.produkte){ 
     htmlInsert+= p.p_name +" Preis: " + p.p_price + " Shopname: "+ 
        p.shop_name + " Quantity: " + p.p_quant + "</br>"; 
    } 

    htmlInsert+= "</p></br>";    
    lines.add(6, htmlInsert); 

    /* WINDOWS Path file = Paths.get(".\\src\\HttpServer\\data.html");*/ 
    /* LINUX*/ Path file = Paths.get("/home/debian/GitRepo/VSSS17/Fridge/src/HttpServer/data.html"); 
    Files.write(file, lines, Charset.forName("UTF-8")); 

} 

static public void decodeData(Produkt data) { 

    Produkt comp = ds.getProduktByName(data.p_name); 
    if (!comp.p_name.equals("Fail")) { 
     //System.out.println("Changed" + data.p_name + "for amount: " + data.p_quant); 
     ds.setQuant(data.p_name, data.p_quant); 
    } else { 
     ds.addProdukt(data); 
    } 

    //System.out.println("---"); 
    if (ds.getLegnth() != 0) { 
    // ds.print(); 
    } 
    //System.out.println("---"); 

} 

}

のでお早めSensordataから私の量が0である、私は私のクライアントに "FILL" 文字列の送信を開始。クライアントは「NOT」パッケージのみを取得します。これは、クライアントが「FILL」パッケージを受け取るまで、約50のパッケージの間続く。この後、数量は100に戻っているので、サーバーは「NOT」パッケージを送信しています。しかし、クライアントは約50のパッケージに対して「FILL」パッケージを受け取ります。私は2つのソケットを開くような別のアタッチメントを持っていました。しかし、それはまだ同じ問題です。

なぜそれが動作しないのか分かりません。インターネット上でそれを見つけることができませんでした。多分あなたたちは私を助けることができます。

+0

UDPには信頼性の機能はありません。信頼性が必要な場合は、自分でコードを作成する必要があります。注:この文脈では、単語は「パッケージ」ではなく「パケット」です。 'データグラム'はまだまだ良いでしょう。 – EJP

+0

ラップされたByteArrayOutputStreamの 'toByteArray()'メソッドを呼び出す前にObjectOutputStream *を 'close()'(少なくとも 'flush()')する必要があります。それは私がコードに入っている限りです。 –

+0

信頼性を達成する最良の方法は何でしょうか?私はそれを受け取った後にのみパケットを送信する方法はありますか?私はUDPとパケット送信でかなり新しいです。 –

答えて

0

私の問題が見つかりました。私は、Serverに一見して4 Packatsを送っていました。サーバーは4つのパケットを送り返していました。私のクライアントがパケットを読んでいた各ループについて、彼は4つの新しいパケットを送り、4つの新しいパケットを取得していました。だからパケットのスタックはちょうど育った。

私は2つのスレッドにクライアントの読み書きを分けました。今すぐ動作します

関連する問題