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

Odpowiedz Nowy wątek
kiepski
2010-03-09 18:18
kiepski
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.

Pozostało 580 znaków

2010-03-09 18:59

Rejestracja: 12 lat temu

Ostatnio: 4 dni temu

0

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

Pozostało 580 znaków

kiepski
2010-03-09 19:31
kiepski
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?

Pozostało 580 znaków

2010-03-09 20:54

Rejestracja: 12 lat temu

Ostatnio: 4 dni temu

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.

Pozostało 580 znaków

eddy_zg
2010-04-02 00:13
eddy_zg
0

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

Wielkie dzięki za wszelką pomoc.

Pozostało 580 znaków

Odpowiedz

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