Klient - serwer, wysyłanie i odbieranie.

0

Witam. Piszę aplikację klient serwer i mam pewien problem. Mianowicie chcę aby serwer wywoływał różne metody w zależności od tego co prześle mu klient. Mam coś takiego:

Klient:

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String text = JOptionPane.showInputDialog(null, "Wprowadz nazwe grupy: ");
        int port = 5500;
        String adresip = "127.0.0.1";
        try {
            InetAddress servAddr = InetAddress.getByName(adresip);
            String data = text;
            byte buf[] = data.getBytes();
            DatagramSocket socket = new DatagramSocket();
            DatagramPacket packet = new DatagramPacket(buf, buf.length, servAddr, port);
            socket.send(packet);
            JOptionPane.showMessageDialog(null, "Wysłano do " + adresip + " nazwę " + text);
        }
        catch(Exception ex) {
            JOptionPane.showMessageDialog(null, "Błąd");
        }
    }                                        
 

Serwer:

    private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {
                int port = 5500;
                try {
                    DatagramSocket socket = new DatagramSocket(port);
                    while(true) {
                        byte buf[] = new byte[100];
                        DatagramPacket packet = new DatagramPacket(buf, buf.length);
                        socket.receive(packet);
                        JOptionPane.showMessageDialog(null, "Odebrano nazwę " + new String(packet.getData()).trim());
                    }
                }
                catch(Exception ex) {
                    JOptionPane.showMessageDialog(null, "Błąd");
                }   
    } 

I ok przesyłanie działa dobrze. Klient wysyła, serwer odbiera. Jednak chciałbym aby klient wysyłał powiedzmy id polecenia do serwera, który odbierze to id i wykona odpowiednią rzecz. Jednak nie wiem jak to zrobić? Logiczne wydaje mi się byłoby wysłanie tego id w buforze. Tylko nie wiem jak je zapisać? Np. te id to zwykłe numerki poleceń 1, 2 itd. Tylko jak je umieścić w buforze? Tak żeby niespecjalnie kolidowało z tekstem jaki przesyłam? Mam jeszcze drugie pytanie. Co jeśli chciałbym przesłać cały obiekt?

            Obiekt data = obiekt;
            byte buf[] = data.getBytes(); 

Jednak to nie działa dla obiektów tak jak dal Stringów. Jak przesłać cały obiekt?

3

Skorzystaj z ObjectOutputStream i ObjectInputStream (serializacja). Omijaj też dalekim łukiem parady dawane przez @maszynaz.

0
bogdans napisał(a):

Skorzystaj z ObjectOutputStream i ObjectInputStream (serializacja). Omijaj też dalekim łukiem parady dawane przez @maszynaz.

To chyba do wysyłania tych obiektów. A jak z tymi id? Chcę np przesłać id i tekst. Jak to wrzucić do bufora? W języku C jak pisałem taki program to zrobiłem strukturę a tutaj nie mam pojęcia.

0

Stwórz klasę, w której będziesz wszystko przechowywał i wyślij zserializowany jej obiekt.

0

Tym razem skorzystaj z rady @maszynaz. Klasa nie musi mieć metod, może pełnić role struktury. Warto ją jednak wyposażyć w metody dostępowe, gettery i settery. Jeśli korzystasz z IDE, to ono samo napisze wszystkie potrzebne Ci gettery i settery.

0

Jak wysłać ten zserializowany obiekt? Jak tworzę new DatagramPacket to nie wiem jakie dwa pierwsze argumenty podać? Muszą być byte[]. Co zrobić z obiektem po serializacji żeby był odpowiedniego typu? oos.writeObject(t);

            InetAddress servAddr = InetAddress.getByName(adresip);
            Tekst t;
            t.num = 1;
            t.tekst = text;
            Socket sock = new Socket();
            ObjectOutputStream oos;
            DatagramSocket socket = new DatagramSocket();
            oos = new ObjectOutputStream( new BufferedOutputStream(sock.getOutputStream()));
            oos.writeObject(t);
            DatagramPacket packet = new DatagramPacket(?, ?, servAddr, port);
            JOptionPane.showMessageDialog(null, "Wysłano do " + adresip + " nazwę " + text);
1

Wysyłanie:

oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(obiekt);

Odbieranie:

ois = new ObjectInputStream(serverSocket.getInputStream());
obiekt = (KlasaObiektu) ois.readObject();
0

Dzięki, wszystko działa. Wysyłam nazwę, serwer ją odbiera, ale potem chcę odesłać z powrotem do klienta komunikat o tym, czy nazwa już istnieje czy też nie i można ją dodać. Niestety ta powtórna wysyłka i odbiór nie działa i sygnalizowany jest błąd. Co jest źle?

Serwer:

    private void jButton9ActionPerformed(java.awt.event.ActionEvent evt) {                                         

                Tekst t;
                int port = 5500;
                String adresip = "127.0.0.1";
                try {
                    ObjectInputStream ois;
                    ServerSocket serverSocket = new ServerSocket(port);
                    Socket sock;
                    sock = serverSocket.accept();
                    ois = new ObjectInputStream(sock.getInputStream());
                    t = (Tekst) ois.readObject();
                    if(t.num == 1) {
                        JOptionPane.showMessageDialog(null, "Odebrano nazwę " + t.tekst);
                        int jest = 0;
                        Socket socket = new Socket(adresip, port);
                        ObjectOutputStream oos;
                        oos = new ObjectOutputStream(socket.getOutputStream());
        
                        for(int i = 0; i < licznik; i++) {
                            if(s.grupy.get(i).nazwaGrupy.equals(t.tekst)) {
                                t.tekst = "Grupa: " + t.tekst + " juz istnieje, podaj inna nazwe";
                                jest++;
                                oos.writeObject(t);
                            }
                        }
                        if(jest == 0) {
                            if(t.tekst != null) {
                                s.grupy.add(new Grupa(t.tekst));
                                JOptionPane.showMessageDialog(null, "Dodano");
                                t.tekst = "Grupa: " + t.tekst + " została dodana";
                                licznik++;
                                oos.writeObject(t);
                            } 
                        }
                    }
                }
                catch(Exception ex) {
                    JOptionPane.showMessageDialog(null, "Błąd");
                }   
    }  

Klient:

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String text = JOptionPane.showInputDialog(null, "Wprowadz nazwe grupy: ");                                       
        int port = 5500;
        String adresip = "127.0.0.1";
        try {
            Tekst t = new Tekst();
            t.num = 1;
            t.tekst = text;
            Socket socket = new Socket(adresip, port);
            ObjectOutputStream oos;
            oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(t);
            JOptionPane.showMessageDialog(null, "Wysłano do " + adresip + " nazwę " + text);
            ObjectInputStream ois;
            ServerSocket serverSocket = new ServerSocket(port);
            Socket sock;
            sock = serverSocket.accept();
            ois = new ObjectInputStream(sock.getInputStream());
            t = (Tekst) ois.readObject();
            JOptionPane.showMessageDialog(null, t.tekst);
        }
        catch(Exception ex) {
            JOptionPane.showMessageDialog(null, "Błąd");
        }
    }  
0

Pomoże ktoś? Błąd jest sygnalizowany przez klienta. Serwer wysyła wiadomość, ale klient jej nie odbiera.

0

Masz mało przydatną obsługę błędów.

catch(Exception e)
{
    e.printStackTrace();
}
0
bogdans napisał(a):

Masz mało przydatną obsługę błędów.

catch(Exception e)
{
    e.printStackTrace();
}

Dostaje błąd: address already in use jvm_bind

0

Zakończ proces javovy

0

Usunąłem te linijki z klienta bo są chyba niepotrzebne:

            //ServerSocket serverSocket = new ServerSocket(port);
            //Socket sock;
            //sock = serverSocket.accept(); 

Teraz błąd nie występuje, ale klient się zawiesza i nic nie odbiera.

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String text = JOptionPane.showInputDialog(null, "Wprowadz nazwe grupy: ");                                       
        int port = 5500;
        String adresip = "127.0.0.1";
        try {
            Tekst t = new Tekst();
            t.num = 1;
            t.tekst = text;
            Socket socket = new Socket(adresip, port);
            ObjectOutputStream oos;
            oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(t);
            JOptionPane.showMessageDialog(null, "Wysłano do " + adresip + " nazwę " + text);
            ObjectInputStream ois;
            //ServerSocket serverSocket = new ServerSocket(port);
            //Socket sock;
            //sock = serverSocket.accept();
            ois = new ObjectInputStream(socket.getInputStream());
            t = (Tekst) ois.readObject();
            JOptionPane.showMessageDialog(null, "Wiadomosc: " + t.tekst);
        }
        catch(Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    } 
1
  1. Nie przestawiłeś kodu klienta i serwera?
  2. Tworzysz połączenia w obsłudze klawiszy (avtionPerformed), wypadało by je zamknąć.
0
bogdans napisał(a):
  1. Nie przestawiłeś kodu klienta i serwera?
  2. Tworzysz połączenia w obsłudze klawiszy (actionPerformed), wypadało by je zamknąć.

Dałem kod, na poprzedniej stronie jest. To jest w buttonach. Bo serwer się tworzy po wciśnięciu przycisku. Klient tak samo. Wysłanie wiadomości od klienta od serwera działa, potem serwer wysyła wiadomość do klienta, ale ta nie dochodzi.

1

Odróżniasz słowa przestawić i przedstawić?
Kod widziałem, ale kod podpisany serwer pasuje do klienta i na odwrót, więc pytam czy nie przestawiłeś kodów. Napisałem też, że nie zamykasz połączeń (oos.close()), a otwierasz nowe z tym samym serwerem.

0

Wszystko działa, tylko, że mogę dodać jedną grupę. Kolejnej serwer nie odbiera.

Serwer:

    private void jButton9ActionPerformed(java.awt.event.ActionEvent evt) {                                         

                Tekst t;
                int port = 5500;
                String adresip = "127.0.0.1";
                try {
                    ObjectInputStream ois;
                    ServerSocket serverSocket = new ServerSocket(port);
                    Socket sock;
                    sock = serverSocket.accept();
                    ois = new ObjectInputStream(sock.getInputStream());
                    ObjectOutputStream oos;
                    oos = new ObjectOutputStream(sock.getOutputStream());
                    t = (Tekst) ois.readObject();
                    if(t.num == 1) {
                        JOptionPane.showMessageDialog(null, "Odebrano nazwę grupy: " + t.tekst);
                        int jest = 0;
        
                        for(int i = 0; i < licznik; i++) {
                            if(s.grupy.get(i).nazwaGrupy.equals(t.tekst)) {
                                t.tekst = "Grupa: " + t.tekst + " juz istnieje, podaj inna nazwę";
                                jest++;
                                oos.writeObject(t);
                            }
                        }
                        if(jest == 0) {
                            if(t.tekst != null) {
                                s.grupy.add(new Grupa(t.tekst));
                                t.tekst = "Grupa: " + t.tekst + " została dodana";
                                licznik++;
                                oos.writeObject(t);
                            } 
                        }
                    }
                    ois.close();
                    oos.close();
                    sock.close();
                }
                catch(Exception ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                }   
    }  
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String text = JOptionPane.showInputDialog(null, "Wprowadz nazwe grupy: ");                                       
        int port = 5500;
        String adresip = "127.0.0.1";
        try {
            Tekst t = new Tekst();
            t.num = 1;
            t.tekst = text;
            Socket socket = new Socket(adresip, port);
            ObjectOutputStream oos;
            oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(t);
            JOptionPane.showMessageDialog(null, "Wysłano do " + adresip + " nazwę: " + text);
            ObjectInputStream ois;
            ois = new ObjectInputStream(socket.getInputStream());
            t = (Tekst) ois.readObject();
            JOptionPane.showMessageDialog(null, t.tekst);
            oos.close();
            ois.close();
            socket.close();
        }
        catch(Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    } 

Próbowałem dodać pętlę while(true) w serwerze przed t = (Tekst) ois.readObject(); ale nie dało to nic. Program działa tak, że wciskam przycisk nasłuchuj w serwerze i tam jest przypisane wszystko co powyżej przedstawiłem. A klient jest pod buttonem dodaj grupę w aplikacji klienta.

0
  1. Serwer ma obsługiwać tylko jednego klienta?
  2. Dlaczego serwer jest uruchamiany kliknięciem w przycisk? Jak nikt nie kliknie, to serwer nie będzie działał? Po mojemu serwer powinien chodzić na okrągło.
  3. Co znaczy, że nie możesz dodać kolejnej grupy? Serwer ją odrzucił, bo nazwa się powtarzała i klient nie może przesłać poprawki, czy też pierwsza grupa została zaakceptowana, a następnej serwer nie odbiera?
0
bogdans napisał(a):
  1. Serwer ma obsługiwać tylko jednego klienta?
  2. Dlaczego serwer jest uruchamiany kliknięciem w przycisk? Jak nikt nie kliknie, to serwer nie będzie działał? Po mojemu serwer powinien chodzić na okrągło.
  3. Co znaczy, że nie możesz dodać kolejnej grupy? Serwer ją odrzucił, bo nazwa się powtarzała i klient nie może przesłać poprawki, czy też pierwsza grupa została zaakceptowana, a następnej serwer nie odbiera?
  1. Pod jednego na razie robię.
  2. Serwer uruchamiany jest po kliknięciu.
  3. Dodaję grupę, serwer ją przyjmuje, odsyła wiadomość do klienta, że została dodana. Potem wysyłam kolejną grupę, ale serwer jej nie odbiera. Nazwa jest inna.
0

A klikasz serwer w międzyczasie?

0
bogdans napisał(a):

A klikasz serwer w międzyczasie?

Nie ma po co bo pisze address, already use in jvm bind. Nie wiem gdzie wrzucić kod serwera, żeby działało na okrągło już od włączenia. Wrzucałem w maina, w konstruktor, wszędzie i wyskakują jakieś błędy, albo po uruchomieniu nic nie widać. Po prostu wrzuciłem to w przycisk. Chyba na jedno wyjdzie jeśli po uruchomieniu aplikacji wciśniemy przycisk i serwer się włączy. Tylko nie bardzo wiem jak zrobić żeby działało na okrągło. Wrzuciłem w pętlę while(true), ale nie działa jak powinno.

1

Ale zamykasz połączenie (sock.close()), musisz zatem gdzieś umieścić serverSocket.accept(). Obiekt sereverSocket twórz raz, ale metodę accept wywołuj w pętli.

0

Witam. Mam mały problem. Mianowicie serwer wysyła do klienta pewną grupę, która chcę edytować. Wszystko ok, wyświetla mi JFrame do edycji, tylko, że przyciski w tym JFrame w ogóle nie reagują. Oto kod:

klient:

                p = (Pakiet) ois.readObject();
                JOptionPane.showMessageDialog(null, p.tekst);
                zg = new ZarzadzajGrupa(p.g);
                zg.setVisible(true); 

Odbiera ten obiekt tworzy nowy JFrame do zarządzania, który wygląda tak:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ZarzadzanieBudynkiem;

import javax.swing.JOptionPane;

/**
 *
 * @author Piotr
 */
public class ZarzadzajGrupa extends javax.swing.JFrame {

    static Grupa grupa;
    
    /**
     * Creates new form ZarzadzajGrupa
     */
    public ZarzadzajGrupa(Grupa g) {
        
        Grupa grupa = g;
        initComponents();
        pack();
        setLocationRelativeTo(null);
        jLabel1.setText("Nazwa grupy: " + grupa.nazwaGrupy);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        grupa.dodajOgrzewanie();
    }                                        

    private void jButton8ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        grupa.dodajKlimatyzacje();
    }                                        

    private void jButton10ActionPerformed(java.awt.event.ActionEvent evt) {                                          
        grupa.dodajSwiatlo();
    }                                         

    private void jButton16ActionPerformed(java.awt.event.ActionEvent evt) {                                          
        grupa.dodajZamek();
    }                                         

    private void jButton20ActionPerformed(java.awt.event.ActionEvent evt) {                                          
        grupa.dodajRolety();
    }                                         

    private void jButton24ActionPerformed(java.awt.event.ActionEvent evt) {                                          

        if(grupa.czujTemp != null) {
            JOptionPane.showMessageDialog(null, "Czujnik temperatury już istnieje");
        } else {
            try {
                String tmp = JOptionPane.showInputDialog(null, "Wprowadź wartość minimalną");
                if(tmp != null) {
                    double min;
                    double max;
                    min = Double.parseDouble(tmp);
                    String tmp1 = JOptionPane.showInputDialog(null, "Wprowadź wartość maksymalną");
                    if(tmp1 != null) {
                        max = Double.parseDouble(tmp1);
                        grupa.dodajCzujnikTemp(min, max);                         
                    } 
                }
            }
            catch ( NumberFormatException e ) {
                JOptionPane.showMessageDialog(null, "Musisz podać liczbę liczbę");
            }                               
        }
    }                                         

    private void jButton28ActionPerformed(java.awt.event.ActionEvent evt) {                                          
        if(grupa.czujRuch != null) {
            JOptionPane.showMessageDialog(null, "Czujnik ruchu już istnieje");
        } else
            grupa.dodajCzujnikRuchu();
        if((grupa.badajRuch() == true) && (grupa.swia != null)) {
            grupa.swia.wlacz();
        }
    }                                         

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        grupa.usunOgrzewanie();
    }                                        

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        if(grupa.ogrz == null) {
            JOptionPane.showMessageDialog(null, "Najpierw dodaj ogrzewanie");
        } else
            grupa.ogrz.wlacz();
    }                                        

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        if(grupa.ogrz == null) {
            JOptionPane.showMessageDialog(null, "Najpierw dodaj ogrzewanie");
        } else
            grupa.ogrz.wylacz();

...

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ZarzadzajGrupa(grupa).setVisible(true);
            }
        });
    }
    }    

Wklejam fragment, bo jest tego więcej, ale w zasadzie reszta to takie same buttony. Tylko zupełnie nie rozumiem, czemu one nie reagują na przyciskanie.

1

Nie używam NetBeans i nie znam kodu generowanego przez designera. Ogólny schemat obsługi klawiszy jest taki:

  • tworzysz przyciski i umieszczasz je w oknie, zakładam że to robisz i przyciski widzisz,
  • dodajesz do przycisku ActionListenera
b.addActionListener(ob);

ob jest obiektem klasy implementującej interfejs ActionListener, w kodzie, który zamieściłeś nie ma takich instrukcji,

  • po kliknięciu w przycisk wykonywana jest metoda actionPerformed obiektu ob, w kodzie, który zamieściłeś nie ma związku między tą metodą a metodami typu jButton23ActionPerformed.
0

Mam kolejny problem. Próbuje przypisać ten przesłany obiekt na serwer, ale wyskakuje błąd "unexpected type found value required variable"

Wygląda to tak:

s.grupy.get(i) = p.g

Jednak nie da się. W przeciwnym kierunku działa.
grupy przechowuje kontener ze zmiennymi Grupa. p.g to obiekt, który został wysłany, g to zmienna typu Grupa

1

Chcesz zmienić element w kolekcji?

s.grupy.remove(i);
s.grupy.add(i,p.g);
0
bogdans napisał(a):
Grupa g = s.grupy.get(i);
g = p.g;

No tak, próbowałem to robić, ale to przecież nie zmienia tego obiektu w kolekcji. Chodzi mi żeby elementowi konkretnemu obiektowi na serwerze s.grupy.get(i) przypisać zmiany, czyli przesłany obiekt od klienta.

Edit: Naprawione, zastąpiłem po prosty ten element poleceniem add.

0

Mój program chodzi w nieskończoność. Tzn. serwer włączany jest przyciskiem włącz i wtedy uruchamia się nieskończona pętla while(true). I tutaj jest problem jak zrobić aby za pomocą innego przycisku wyłączyć serwer? Kiedy włączam przycisk włącz to uruchamia się ta pętla i na serwerze nie da się przycisnąć nic innego.

0

Musisz mieć dwa wątki, wątek obsługi zdarzeń i wątek nasłuchiwania w sieci.

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