połączenie serwer-klient i blokujący się interfejs graficzny

0

witajcie drodzy forumowicze...

/**
 * @(#)Multiczat.java
 *
 *
 * @author Michał Płatek 
 * @version 1.00 2010/3/4
 */
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

public class Multiczat 
{


	public static void main(String[] args)
	{
		Ramka ramka = new Ramka();								// tworzymy obiekt typu Ramka
		ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // po zamknięciu ramki program kończy działanie
		ramka.show();											// wyświetlenie ramki na ekranie
	}
    
}

class Ramka extends JFrame
{
	public Ramka()
	{
		
		//pobieram rozdzielczość ekranu
		Toolkit zestaw = Toolkit.getDefaultToolkit(); 
		Dimension rozmiarEkranu = zestaw.getScreenSize();
		int wysEkranu = rozmiarEkranu.height;
		int szerEkranu = rozmiarEkranu.width;
		
		setSize(szerEkranu-150, wysEkranu-150);	// zmienia rozmiar ramki na jedną czwartą całego ekranu
		setLocation(szerEkranu / 10, wysEkranu / 10); // zmienia położenie ramki na środek ekranu
		
		//określa ikonę i tytuł ramki
		setTitle("Multiczat"); 		// określa tekst znajdujący sie w pasku tytułowym ramki
		Image rys = zestaw.getImage("ikona.jpg");
		setIconImage(rys);
		setResizable(false);
		
		//konstruuje przyciski
		//PRZYCISKI
		JButton server_button = new JButton("Start Server");
		JButton client_button = new JButton("Start Client");
		JButton send_message = new JButton("Wyślij");
		JButton send_file = new JButton("Send File");
		JButton logout = new JButton("Logout");
		
		//stworzenie pól tekstowych
		server_port = new JTextField(10);
		server_port.setMaximumSize(server_port.getPreferredSize());
		server_port.setText("2023");
		client_host = new JTextField(10);
		client_host.setMaximumSize(client_host.getPreferredSize());
		client_host.setText("localhost");
		client_port = new JTextField(10);
		client_port.setMaximumSize(client_port.getPreferredSize());
		client_port.setText("2023");
		
		message = new JTextField(50);
		message.setMaximumSize(message.getPreferredSize());
		
		//tworzy obszar okna czatu
		chat = new JTextArea(20,10);
		chat.setMaximumSize(chat.getPreferredSize());
		chat.setEditable(false);
		Font font = new Font("Times New Roman SE",Font.PLAIN, 16);
		JScrollPane chat_scroll = new JScrollPane(chat);
		chat_scroll.setBorder(new TitledBorder(new EtchedBorder(), "Czat: ", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION,font));
		
		/////////////////////////////////
		message.setText("TO DO WYSŁANIA");
		chat.setFont(font);
		chat.append("- hello");
		chat.append("\n");
		chat.append("- nie hello");	chat.append("- nie hello");	chat.append("- nie hello");
		//////////////////////////////
		
		
		//tworzy obszar listy uzytkownikow 
 		JTextArea user_list = new JTextArea(20, 15);
		user_list.setMaximumSize(user_list.getPreferredSize());
		
		
		Border wytrawiona1 = BorderFactory.createEtchedBorder();
		Border nazwana1 = BorderFactory.createTitledBorder(wytrawiona1, "Lista użytkowników:");
		user_list.setBorder(nazwana1);

		
		
		
		////////////UKŁAD PUDEŁKOWY!!
		//układ pudełkowy
		Box ukladPoziom1 = Box.createHorizontalBox();
		ukladPoziom1.add(Box.createHorizontalStrut(10));
		ukladPoziom1.add(Etykieta("Port:  "));  
		ukladPoziom1.add(server_port);
		ukladPoziom1.add(server_button);
		ukladPoziom1.add(Box.createHorizontalStrut(30));
		ukladPoziom1.add(Etykieta("Host:  "));  
		ukladPoziom1.add(client_host);
		ukladPoziom1.add(Etykieta("Port:  "));  
		ukladPoziom1.add(client_port);
		ukladPoziom1.add(client_button);
		ukladPoziom1.add(Box.createHorizontalStrut(100));
		ukladPoziom1.add(logout);
		 
		Box ukladPoziom2 = Box.createHorizontalBox(); 	
		ukladPoziom2.add(message);
		ukladPoziom2.add(Box.createHorizontalStrut(15));
		ukladPoziom2.add(send_message);
		 
		Box ukladPion1 = Box.createVerticalBox();
		ukladPion1.add(chat_scroll);
		ukladPion1.add(ukladPoziom2); 
		 
		Box uklad_poz2 = Box.createHorizontalBox();
		uklad_poz2.add(ukladPion1);
		uklad_poz2.add(Box.createHorizontalStrut(15));
	    uklad_poz2.add(user_list);
			
		Box uklad = Box.createVerticalBox();
		uklad.add(ukladPoziom1);
		uklad.add(uklad_poz2);
		
		Container powZawartosci = getContentPane();
		powZawartosci.add(uklad, BorderLayout.CENTER);
		
		

		
		//konstruuje działania przycisków
		action_server_button action = new action_server_button();
		server_button.addActionListener(action);
		
		action_client_button action2 = new action_client_button();
		client_button.addActionListener(action2);
	}
	

//klasa publiczna tworząca etykiety	
public JLabel Etykieta(String nazwa)
	{
	   return new JLabel(nazwa);
	}
	
	
	
//SLUCHACZE - prywatne klasy	

// określa działanie po naciśnięciu przycisku 'server_button'
private class action_server_button implements ActionListener
{
	
	public void actionPerformed(ActionEvent zdarzenie)
	{
		int port_number=2023;
		
			try
			{
				//uruchamianie gniazda serwera na porcie
				ServerSocket server = new ServerSocket(port_number);
				System.out.println("od SERWER: Serwer wystartował!");
				System.out.println("od SERWER: Oczekiwanie na klienta...");
	
				//wyświetlenie okna dialogowego z informacją o wystartowaniu serwera
				JOptionPane.showMessageDialog(null, "Serwer wystartował na porcie: " + port_number);
		
		
				int i = 1;
				
				while(true)
					{
				//oczekiwanie i akceptacja połączenia z klientem
				Socket socket = server.accept();
				System.out.println("od SERWER: Jest klient. To już "+i+" klient.");
				Runnable r = new ThreadedEchoHandler(socket, i);
				Thread t = new Thread(r);
				t.start();
				i++;
					}	

                    
                }
				
		
				//System.out.println("od SERWER: Zamknięcie strumieni.");
				//socket.close();
			
			
catch(UnknownHostException e) 
{
	// Nieznany host 
  	System.out.println("od SERWER: Błąd nieznany host.");
} 
catch (IOException e)
{
	// Błąd operacji wejścia/wyjścia
	System.out.println("OD SERWER: Błąd operacji wejścia/wyjścia");
} 
    	 
	}		
}




// określa działanie po naciśnięciu przycisku 'client_button'
class action_client_button implements ActionListener
{
				
	public void actionPerformed(ActionEvent zdarzenie)
	{
		int port_number=2023;
		
			try
			{
				socket = new Socket("localhost", port_number);
		        System.out.println("OD KLIENT: Pomyślnie połączono z serwerem..");
		        
		        
		        in= socket.getInputStream();
                out= socket.getOutputStream();

                BufferedReader comandline= new BufferedReader(new InputStreamReader(System.in));
                int k=0;
                
                while(true)
                	{	
                    System.out.println("Wprowadz napis:");
                    String line= comandline.readLine();
                    out.write(line.getBytes());
                   out.write(("\n").getBytes());
                   
               		while((k=in.read())!= '\n')
                	{
               		System.out.print((char)k);
               	 	}
    
                   }
              
		        
				
				//System.out.println("OD KLIENT: Zamknięcie strumieni.");
				//socket.close();
			} 
			
catch(UnknownHostException e) 
{
	// Nieznany host 
  	System.out.println("OD KLIENT: Błąd nieznany host.");

} 
catch (IOException e)
{
	// Błąd operacji wejścia/wyjścia
	System.out.println("OD KLIENT: Błąd operacji wejścia/wyjścia");
    
    //wyświetlenie okna dialogowego z informacją o nie znalezieniu serwera na tym porcie
	JOptionPane.showMessageDialog(null, "Nie znaleziono serwera na porcie: " + port_number);
} 
    	 
		}
}





/**
 Klasa obsługująca komunikację z pojedynczym klientem
*/
class ThreadedEchoHandler implements Runnable
{
	public ThreadedEchoHandler(Socket i, int c)
	{
		socket = i; 
		counter = c;
	}
	
	public void run()
	{
	
	try{

		
	in = socket.getInputStream();
	out = socket.getOutputStream();	 
		        
	BufferedReader comandline= new BufferedReader(new InputStreamReader(System.in));
    int k=0;
    while(true)
     {
     while((k=in.read())!= '\n')
               	{
               System.out.print((char)k);
                }
      System.out.println("Wprowadz napis:");
      String line= comandline.readLine();
      out.write(line.getBytes());
      out.write(("\n").getBytes());
	}
	}
catch(UnknownHostException e) 
{
	// Nieznany host 
  	System.out.println("OD KLIENT: Błąd nieznany host.");

} 
catch (IOException e)
{
	// Błąd operacji wejścia/wyjścia
	System.out.println("OD KLIENT: Błąd operacji wejścia/wyjścia");	
}
	
}
}

//prywatne pola klasy
JTextArea chat;
JTextField message;

JTextField server_port;
JTextField client_port;
JTextField client_host;

private Socket socket;
private int counter;
InputStream in;
OutputStream out;
}

Próbuje napisać chat w Javie. Otóż zacząłem od prostego interfejsu graficznego. Napisałem proste metody łączące wiele klientów z serwerem. Wszystko ładnie cacy. Komunikacja w konsoli jest. Tylko dlaczego po połączeniu interfejs graficzny się blokuje i nie można nic na nim robić? Proszę o pomoc.

0

Nie widzę nigdzie odpalonego osobnego wątku dla komunikacji. GUI i transmisja muszą chodzić w osobnych wątkach.

0

właśnie prosiłbym o pomoc w tym problemie. Powiedzmy w GUI w utworzonym polu tekstowym 'message' chciałbym wpisać pobrane dane od klienta/serwera. W jaki sposob utworzyć ten nowy wątek? Bo naprawdę nie wiem jak się za to zabrać. Proszę chociaż o wskazówki.

Co ma być tym drugim uruchomionym procesem? cała metoda main? Proszę o jakąkolwiek pomoc. I w jaki sposób tym sterowac?

0

W wątku uruchamiasz część odpowiedzialną za komunikację. Nie wiem jak to jaśniej. W Kody źródłowe masz przykładowy serwer wielowątkowy.

0

Mógłbyś jeszcze raz wrzucić "Klientserver multithreaded.zip" bo chyba się usunął z serwera ?

Wielkie dzięki za wszelką pomoc.

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