少し大学のプロジェクト私はサーバーとクライアントの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つのソケットを開くような別のアタッチメントを持っていました。しかし、それはまだ同じ問題です。
なぜそれが動作しないのか分かりません。インターネット上でそれを見つけることができませんでした。多分あなたたちは私を助けることができます。
UDPには信頼性の機能はありません。信頼性が必要な場合は、自分でコードを作成する必要があります。注:この文脈では、単語は「パッケージ」ではなく「パケット」です。 'データグラム'はまだまだ良いでしょう。 – EJP
ラップされたByteArrayOutputStreamの 'toByteArray()'メソッドを呼び出す前にObjectOutputStream *を 'close()'(少なくとも 'flush()')する必要があります。それは私がコードに入っている限りです。 –
信頼性を達成する最良の方法は何でしょうか?私はそれを受け取った後にのみパケットを送信する方法はありますか?私はUDPとパケット送信でかなり新しいです。 –