[ watki ] ponawianie w razie niepowodzenia

0

Witam. Moj problem jest nastepujacy...Aplikacja wysyla wiadomosc tekstowa do 5 klientow naraz( Komputerowy System POwiadamiania Grupowego) ,tylu znajduje sie w jednej zakladce (JTabbedPane). Moje pytanie jest nastepujace. W jaki sposob ponowic wyslanie wiadomosci,w wypadku jej nie dostarczenia? Jednak tylko do tych klientow,do ktorych nie dotarla,a nie wszystkich 5ciu? Zapewn chodzi o watki,jednak nie wiem jak taki stworzyc? Musi byc osobny watek dla kazdego klienta? Z gory dzieki za zainteresowanie :-) . Ponizej kod...


klasa MainClass

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.text.Document;


/*
 * Created on 2007-04-16
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author yossarian
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class MainClass extends JFrame implements ActionListener, Runnable{
	
	
	JTextArea pole = new JTextArea();;
	Font czcionka = new Font("Serif",Font.BOLD,17);
	JFrame ramka;
	String wartosc;
	Document dok;
	JButton pisz1, pisz2, pisz3;
	JButton wyslij1, wyslij2, wyslij3;
	String msg;
	JPanel panel1;
	JPanel panel2;
	JPanel panel3;
	JTabbedPane zakladki;
	String ip = "don";
	Icon gif_T = new ImageIcon("jest.gif");
	Icon gif_F = new ImageIcon("stop.gif");
	Icon gif_N = new ImageIcon("neutral.gif");
	JLabel icon1,icon2,icon3,icon4,icon5,icon11,icon22,icon33,icon44,icon55,icon111,icon222,icon333,icon444,icon555;
	Process p;
	Watek_polaczenia1 wpol1;
	
	public MainClass(){
		
		wpol1 = new Watek_polaczenia1(this);
		
		zakladka1();
		zakladka2();
		zakladka3();
		
		//dodajemy zakladke,zby byla widoczna
		zakladki = new JTabbedPane();
		zakladki.addTab("oficer", panel1);
		zakladki.addTab("oficerowie", panel2);
		zakladki.addTab("pod ofic.", panel3);
		
		setContentPane(zakladki);
		pack();
		setTitle("System powiadamiania");		
		setResizable(false);
		setSize(250,450);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		
	}
	

	
	public void zakladka1(){
		//pierwsza zakladka
			
		icon1 = new JLabel(gif_N);
		icon1.setBounds(120,50,100,80);
		//icon1.setEnabled(false);
		
		icon2 = new JLabel(gif_N);
		icon2.setBounds(120,100,100,80);
		
		icon3 = new JLabel(gif_N);
		icon3.setBounds(120,150,100,80);
		
		icon4 = new JLabel(gif_N);
		icon4.setBounds(120,200,100,80);
		
		icon5 = new JLabel(gif_N);
		icon5.setBounds(120,250,100,80);
		
		panel1 = new JPanel();
		panel1.setBackground(Color.green);
		panel1.setLayout(null);//new GridLayout(0,1));
		pisz1 = new JButton("napisz");
		pisz1.setBounds(0,0,239,65);
		pisz1.addActionListener(this);
		panel1.add(pisz1);

		JLabel user1 = new JLabel("Oleksy");
		user1.setBounds(5,50,100,80);
		user1.setFont(czcionka);
		JLabel user2 = new JLabel("Kowalski");
		user2.setBounds(5,100,100,80);
		user2.setFont(czcionka);
		JLabel user3 = new JLabel("Majdan");
		user3.setBounds(5,150,100,80);
		user3.setFont(czcionka);
		JLabel user4 = new JLabel("Wojewod");
		user4.setBounds(5,200,100,80);
		user4.setFont(czcionka);
		JLabel user5 = new JLabel("Giertych");
		user5.setBounds(5,250,100,80);
		user5.setFont(czcionka);
					
		panel1.add(user1);
		panel1.add(user2);
		panel1.add(user3);
		panel1.add(user4);
		panel1.add(user5);
		panel1.add(icon1);
		panel1.add(icon2);
		panel1.add(icon3);
		panel1.add(icon4);
		panel1.add(icon5);
		
	}
	public void zakladka2(){
//		druga zakladka "oficerowie"
			
		icon11 = new JLabel(gif_N);
		icon11.setBounds(120,50,100,80);
		//icon1.setEnabled(false);
		
		icon22 = new JLabel(gif_N);
		icon22.setBounds(120,100,100,80);
		
		icon33 = new JLabel(gif_N);
		icon33.setBounds(120,150,100,80);
		
		icon44 = new JLabel(gif_N);
		icon44.setBounds(120,200,100,80);
		
		icon55 = new JLabel(gif_N);
		icon55.setBounds(120,250,100,80);
		
		panel2 = new JPanel();
		panel2.setBackground(Color.magenta);
		panel2.setLayout(null);//new GridLayout(0,1));
		pisz2 = new JButton("napisz");
		pisz2.setBounds(0,0,239,65);
		pisz2.addActionListener(this);
		panel2.add(pisz2);

		JLabel user11 = new JLabel("Zurawski");
		user11.setBounds(5,50,100,80);
		user11.setFont(czcionka);
		JLabel user22 = new JLabel("Don_Kozetti");
		user22.setBounds(5,100,100,80);
		user22.setFont(czcionka);
		JLabel user33 = new JLabel("Engell");
		user33.setBounds(5,150,100,80);
		user33.setFont(czcionka);
		JLabel user44 = new JLabel("Jagus");
		user44.setBounds(5,200,100,80);
		user44.setFont(czcionka);
		JLabel user55 = new JLabel("Gollob");
		user55.setBounds(5,250,100,80);
		user55.setFont(czcionka);
					
		panel2.add(user11);
		panel2.add(user22);
		panel2.add(user33);
		panel2.add(user44);
		panel2.add(user55);
		panel2.add(icon11);
		panel2.add(icon22);
		panel2.add(icon33);
		panel2.add(icon44);
		panel2.add(icon55);
		
	}
	public void zakladka3(){

		icon111 = new JLabel(gif_N);
		icon111.setBounds(120,50,100,80);
		//icon1.setEnabled(false);
		
		icon222 = new JLabel(gif_N);
		icon222.setBounds(120,100,100,80);
		
		icon333 = new JLabel(gif_N);
		icon333.setBounds(120,150,100,80);
		
		icon444 = new JLabel(gif_N);
		icon444.setBounds(120,200,100,80);
		
		icon555 = new JLabel(gif_N);
		icon555.setBounds(120,250,100,80);
		
		
		panel3 = new JPanel();
		panel3.setBackground(Color.yellow);
		panel3.setLayout(null);//new GridLayout(0,1));
		pisz3 = new JButton("napisz");
		pisz3.setBounds(0,0,239,65);
		pisz3.addActionListener(this);
		panel3.add(pisz3);

		JLabel user111 = new JLabel("Kieslowski");
		user111.setBounds(5,50,100,80);
		user111.setFont(czcionka);
		JLabel user222 = new JLabel("Polanski");
		user222.setBounds(5,100,100,80);
		user222.setFont(czcionka);
		JLabel user333 = new JLabel("Latkowski");
		user333.setBounds(5,150,100,80);
		user333.setFont(czcionka);
		JLabel user444 = new JLabel("Stuhr");
		user444.setBounds(5,200,100,80);
		user444.setFont(czcionka);
		JLabel user555 = new JLabel("Krause");
		user555.setBounds(5,250,100,80);
		user555.setFont(czcionka);
					
		panel3.add(user111);
		panel3.add(user222);
		panel3.add(user333);
		panel3.add(user444);
		panel3.add(user555);
		panel3.add(icon111);
		panel3.add(icon222);
		panel3.add(icon333);
		panel3.add(icon444);
		panel3.add(icon555);
			
		
		
	}
	
public void wiadomosc1(){
	
		ramka = new JFrame("napisz wiadomosc");
		Container kontener = ramka.getContentPane();
		
		//pole = new JTextArea();
		pole.setFont(new Font("Serif",Font.BOLD,17));
		
		pole.setBackground(Color.green);
		pole.setForeground(Color.BLACK);
		
	
		JPanel panel_button = new JPanel();
		wyslij1 = new JButton("Wyślij");
		wyslij1.addActionListener(this);
		//guzik.setToolTipText(komentarz);
		panel_button.add(wyslij1);
		
		
		kontener.add(BorderLayout.NORTH,pole);
		kontener.add(new JScrollPane(pole));
		kontener.add(BorderLayout.SOUTH,panel_button);
		
		
		ramka.pack();
		ramka.setTitle("wiadomosc");
		ramka.setSize(300,200);
		ramka.setResizable(false);
		//ramka.setDefaultCloseOperation(EXIT_ON_CLOSE);
		ramka.setLocationRelativeTo(null);
		ramka.setVisible(true);
		
	}
	


	public static void main(String[] args) {
		MainClass nowy = new MainClass();
		
	}
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		
		if(e.getSource()==pisz1){
			//licznik();
			wiadomosc1();
			
		}
		if(e.getSource()==wyslij1){
			new Thread(wpol1).start();
			ramka.dispose();
		}
		
	}

	


	public void run() {
		int n =0;
		while(true){
			n++;
			System.out.println("watek 1 ping wykonuje kolejna petle (nr"+n+")");
			try{
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
}
	}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
klasa Watek_polaczenia1

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;


public class Watek_polaczenia1 implements Runnable{
	
	
	String ip1 = "192.168.1.11";
	String ip2 = "192.168.1.10";
	String ip3 = "89.229.20.88";
	String ip4 = "192.168.1.14";
	String ip5 = "192.168.1.15";
	Socket klient1, klient2, klient3, klient4,klient5;
	DataInputStream wejscie;
	DataOutputStream wyjscie;
	String msg;
	JButton wyslij1,wyslij2,wyslij3;
	JPanel panel1,panel2,panel3;
	MainClass serwerClass;
	Icon gif_T = new ImageIcon("jest.gif");
	Icon gif_F = new ImageIcon("stop.gif");
	Icon gif_N = new ImageIcon("neutral.gif");
	boolean flaga=true;
	
		
public Watek_polaczenia1(MainClass serwerClass) {
	
		this.serwerClass = serwerClass; 

	}

	
	public void run(){
		int i = 0;
		System.out.println("Teraz niby nastepuje polaczenie ");
	do{	
	//for(int q=0;q<1;q++){
		//do{
		i++;
		//while(true){
	System.out.println("watek pol1 powtarza co okreslony czas(nr"+i+")\n");

	polaczenie1();
		}while(!flaga);
	}
	
	public void polaczenie1(){
		
		
		msg = serwerClass.pole.getText();
		
		
		//pierwszy powiadamiany
		try{
		klient1 = new Socket(ip1,1234);
		//wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
		
		wyjscie = new DataOutputStream(new BufferedOutputStream(klient1.getOutputStream()));
		try{
		
		wyjscie.writeUTF(msg);
		}catch(NullPointerException e){
			
		}
		wyjscie.close();
		klient1.close();
		if(klient1.isConnected())
			System.out.println("Polaczyles sie z " +klient1);
		serwerClass.icon1.setIcon(gif_T);
		
		}catch(IOException e){
			System.out.println("Polaczenie nie udalo sie" +klient1);
			serwerClass.icon1.setIcon(gif_F);
//i tu powinno nastapic ponowienie wyslania,zapewne kolejny watek,ale tylko dla tego danego ip(tu akurat ip1)
????????????????????????????????????????????????????????????????????????

		}
	
		
 //drugi powiadamiany
		try{
			klient2 = new Socket(ip2,1234);
			//wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
			
			wyjscie = new DataOutputStream(new BufferedOutputStream(klient2.getOutputStream()));
			try{
			wyjscie.writeUTF(msg);
			}catch(NullPointerException e){
				
			}
			wyjscie.close();
			klient2.close();
			if(klient2.isConnected())
				System.out.println("Polaczyles sie z " +klient2);
			serwerClass.icon2.setIcon(gif_T);
			
			}catch(IOException e){
				System.out.println("Polaczenie nie udalo sie" +klient2);
				serwerClass.icon2.setIcon(gif_F);
				
			}
			//flaga = false;

//	trzeci powiadamiany
	try{
		klient3 = new Socket(ip3,1234);
		//wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
		
		wyjscie = new DataOutputStream(new BufferedOutputStream(klient3.getOutputStream()));
		try{
		wyjscie.writeUTF(msg);
		}catch(NullPointerException e){
			
		}
		wyjscie.close();
		klient3.close();
		//wyjscie = pole.getText();
		if(klient3.isConnected())
			System.out.println("Polaczyles sie z " +klient3);
		
		}catch(IOException e){
			System.out.println("Polaczenie nie udalo sie" +klient3);
		}
	
		//czwarty powiadamiany
		try{
			klient4 = new Socket(ip4,1234);
			//wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
			
			wyjscie = new DataOutputStream(new BufferedOutputStream(klient4.getOutputStream()));
			try{
			wyjscie.writeUTF(msg);
			}catch(NullPointerException e){
				
			}
			wyjscie.close();
			klient4.close();
			//wyjscie = pole.getText();
			if(klient4.isConnected())
				System.out.println("Polaczyles sie z " +klient4);
			
			}catch(IOException e){
				System.out.println("Polaczenie nie udalo sie" +klient4);
			}
			
			//piaty powiadamiany
			try{
				klient5 = new Socket(ip5,1234);
				//wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
				
				wyjscie = new DataOutputStream(new BufferedOutputStream(klient5.getOutputStream()));
				try{
				wyjscie.writeUTF(msg);
				}catch(NullPointerException e){
					
				}
				wyjscie.close();
				klient5.close();
				//wyjscie = pole.getText();
				if(klient5.isConnected())
					System.out.println("Polaczyles sie z " +klient5);
				
				}catch(IOException e){
					System.out.println("Polaczenie nie udalo sie" +klient5);
				}

}
}
0

W końcu jakiś rozsądny problem :)
Twój kod:

  public void polaczenie1(){
               
               
                msg = serwerClass.pole.getText();
               
               
                //pierwszy powiadamiany
                try{
                klient1 = new Socket(ip1,1234);
                //wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
               
                wyjscie = new DataOutputStream(new BufferedOutputStream(klient1.getOutputStream()));
                try{
               
                wyjscie.writeUTF(msg);
                }catch(NullPointerException e){
                       
                }
                wyjscie.close();
                klient1.close();
                if(klient1.isConnected())
                        System.out.println("Polaczyles sie z " +klient1);
                serwerClass.icon1.setIcon(gif_T);
               
                }catch(IOException e){
                        System.out.println("Polaczenie nie udalo sie" +klient1);
                        serwerClass.icon1.setIcon(gif_F);
//i tu powinno nastapic ponowienie wyslania,zapewne kolejny watek,ale tylko dla tego danego ip(tu akurat ip1)
????????????????????????????????????????????????????????????????????????

                }
       
               
 //drugi powiadamiany
                try{
                        klient2 = new Socket(ip2,1234);
                        //wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
                       
                        wyjscie = new DataOutputStream(new BufferedOutputStream(klient2.getOutputStream()));
                        try{
                        wyjscie.writeUTF(msg);
                        }catch(NullPointerException e){
                               
                        }
                        wyjscie.close();
                        klient2.close();
                        if(klient2.isConnected())
                                System.out.println("Polaczyles sie z " +klient2);
                        serwerClass.icon2.setIcon(gif_T);
                       
                        }catch(IOException e){
                                System.out.println("Polaczenie nie udalo sie" +klient2);
                                serwerClass.icon2.setIcon(gif_F);
                               
                        }
                        //flaga = false;

//        trzeci powiadamiany
        try{
                klient3 = new Socket(ip3,1234);
                //wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
               
                wyjscie = new DataOutputStream(new BufferedOutputStream(klient3.getOutputStream()));
                try{
                wyjscie.writeUTF(msg);
                }catch(NullPointerException e){
                       
                }
                wyjscie.close();
                klient3.close();
                //wyjscie = pole.getText();
                if(klient3.isConnected())
                        System.out.println("Polaczyles sie z " +klient3);
               
                }catch(IOException e){
                        System.out.println("Polaczenie nie udalo sie" +klient3);
                }
       
                //czwarty powiadamiany
                try{
                        klient4 = new Socket(ip4,1234);
                        //wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
                       
                        wyjscie = new DataOutputStream(new BufferedOutputStream(klient4.getOutputStream()));
                        try{
                        wyjscie.writeUTF(msg);
                        }catch(NullPointerException e){
                               
                        }
                        wyjscie.close();
                        klient4.close();
                        //wyjscie = pole.getText();
                        if(klient4.isConnected())
                                System.out.println("Polaczyles sie z " +klient4);
                       
                        }catch(IOException e){
                                System.out.println("Polaczenie nie udalo sie" +klient4);
                        }
                       
                        //piaty powiadamiany
                        try{
                                klient5 = new Socket(ip5,1234);
                                //wejscie = new DataInputStream(new BufferedInputStream(klient1.getInputStream()));
                               
                                wyjscie = new DataOutputStream(new BufferedOutputStream(klient5.getOutputStream()));
                                try{
                                wyjscie.writeUTF(msg);
                                }catch(NullPointerException e){
                                       
                                }
                                wyjscie.close();
                                klient5.close();
                                //wyjscie = pole.getText();
                                if(klient5.isConnected())
                                        System.out.println("Polaczyles sie z " +klient5);
                               
                                }catch(IOException e){
                                        System.out.println("Polaczenie nie udalo sie" +klient5);
                                }

}

Należy zdecydowanie uprościć. Na początek pytanie co się stanie jak będziesz chciał wysłać wiadomość do 6 klienta? Oczywioście musisz przerobić klasę :D Huraaa!
Powtarzasz kod aż pięciokrotnie, a jedyną różnicą są dane klienta. Piszemy zatem:

import java.net.Socket;

public class Client {
	private String ip;

	private int port;

	private Socket socket;

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public Socket getSocket() {
		return socket;
	}

	public void setSocket(Socket socket) {
		this.socket = socket;
	}

}

Jak mamy już klienta to możemy zajać się wysyłaniem wiadomości. I tu uwaga. Dość boleśnie wymieszałeś widok aplikacji z funkcjonalnością jaką jest wysłanie wiadomości. Teraz ciężka decyzja. Czy wysyłamy wiadomość dla każdego z klientów w osobnym wątku czy też wszytkich w jednym?
Wybrnąć można z tego dość łatwo tworząc klase abstrakcyjną + interfejs, ale my będziemy twardzi i upchniemy to w jednym osobnym wątku.
Nierozumiem po co jest ten fragment:

  do{       
        //for(int q=0;q<1;q++){
                //do{
                i++;
                //while(true){
        System.out.println("watek pol1 powtarza co okreslony czas(nr"+i+")\n");

        polaczenie1();
                }while(!flaga);
        }

Jak chcesz raz na pewien czas coś wysłać to lepiej już zrobić sobie klasę która będzie sobie działała w tle i co pewien czas wykonywała jakieś operacje.... ale nie o tym teraz piszemy. Poza tym:

catch(NullPointerException e){}

jest poważnym błędem ponieważ NullPointer jest ogólniej błędem grupy Runtime ich się nie wyłapuje. Pojawienie się takiego błędu oznacza błąd w konstrukcji programu. Lepiej jest używać:

if(cosCoMozeBycNullem == null){
   //reakcja na nulla
}
else{/*...*/}

Dobra klasa wysyłająca :

public class Sender extends Thread {
	
	private String msg;
	
	private List<Client> klienci;

	private boolean running;
	
	public Sender(String msg, List<Client> klienci) {
		this.msg = msg;
		this.klienci = klienci;
	}

	public void run(){
		while(running)
			wyslij();
	}
	
	private void wyslij(){
		Socket s = null;
		DataOutputStream dos = null;
		BufferedOutputStream bos;
		for (Client c : klienci){
			try{
				s = c.getSocket();
				bos = new BufferedOutputStream(s.getOutputStream());
				dos= new DataOutputStream(bos);
				dos.writeUTF(msg);
			}
			catch(IOException e){
                System.out.println("Polaczenie nie udalo sie" +c.getIp());
            
			}
			finally{
				try {
					if(dos != null)
						dos.close();
					if(s != null)
						s.close();
					
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
}

oraz jej uruchomienie:

Sender s = new Sender("Wiadomość", listaKlientow);
s.run();

Jeszcze na koniec tworzenie klientów:

List<Client> listaKlientow = new LinkedList<Client>();
Client c1 = new Client();
c1.setIp("127.0.0.0");
c1.setPort(1234);
listaKlientow.add(c1);
Client c2 = new Client();
//....

Na początek tyle ;) Popraw kod i wtedy można przystapić do obsługi błędów wysyłania.
Na początek należy przygotować zabawkę do ponawiania wysyłki:

public class NotSendedMsg {

	public List<ClientMsg> listaZlych = new LinkedList<ClientMsg>();

	public void add(ClientMsg clientMsg) {
		listaZlych.add(clientMsg);
	}

	public void ponow(Sender s) {
		s.run();
	}
}

class ClientMsg {
	Client c;

	String msg;

	public ClientMsg(Client c, String msg) {
		this.c = c;
		this.msg = msg;
	}

}

Oraz zmodyfikować kod Sendera:


public NotSendedMsg nsm = new NotSendedMsg();
//...
} catch (IOException e) {
	System.out.println("Polaczenie nie udalo sie" + c.getIp());
	nsm.add(new ClientMsg(c, msg));
}

Następnie należy R ĘCZNIE wywoływać ponawianie!

Co można poprawić? Poszukaj informacji o wzorcu Singleton i przerób NotSendedMsg tak by była singletonem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1