多客户端 - 服务器 - 每个新客户端如何查看变量的当前值?

时间:2014-03-07 21:14:37

标签: java sockets

我正在尝试制作客户端 - 服务器应用程序。它是关于图书馆的,每个新客户都必须看到当前的图书库存。我不知道,当新客户启动时服务器如何发送实际库存。在我的应用程序中,新客户始终可以查看最初的书籍库存。有什么建议?提前致谢。这是我的代码:

服务器

package Server;

import java.io.*;
import java.net.*;
import java.util.*;

import javax.swing.JOptionPane;

class Readers {
    private ArrayList<PrintWriter> pW;

    public Readers() {
        pW = new ArrayList<PrintWriter>(10);
    }

    public synchronized void addR(PrintWriter p) {
        pW.add(p);
    }

    public synchronized void rmvR(PrintWriter p) {
        pW.remove(p);
    }

    public synchronized void sendR(String s) {
        Iterator<PrintWriter> itr = pW.iterator();
        while (itr.hasNext()) {
            PrintWriter p = (PrintWriter) itr.next();
            p.println(s);
        }
    }

}


class ServeOneReader extends Thread {
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    public static int available1=3;//initial stock of book 1
    public static int available2=3;//initial stock of book 2
    String book1 = "The cat in the had";
    String book2 = "Harry Potter";
    Readers rd;

    public ServeOneReader(Socket s, Readers rd) throws IOException {
        socket = s;
        this.rd = rd;
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        // Enable auto-flush:
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                socket.getOutputStream())), true);
        // If any of the above calls throw an
        // exception, the caller is responsible for
        // closing the socket. Otherwise the thread
        // will close it.
        rd.addR(out);
        start(); // Calls run()
    }

    public void run() {
        try {
            while (true) {
                String str = in.readLine();//client sends suffix "borrowed" or "returned" after book's name
                if (str.equals(book1 + "borrow")) {//check if the book was borrowed
                        available1--;
                        System.out.println("Book " + str + " Stock: " + available1);
                        String answer = book1 + " Stock: " + available1;
                        rd.sendR(answer);
                        out.println(book1);//Server sends back the book's name to the client to identify which stock decreases 
                        out.println(available1);//stock of book 1
                }
                if (str.equals(book2 + "borrow")) {//check if the book was borrowed
                        available2--;
                        System.out.println("Book " + str + " Stock: " + available2);
                        String answer = book2 + " Stock: " + available2;
                        rd.sendR(answer);
                        out.println(book2);
                        out.println(available2);

                }
                if (str.equals(book1 + "returned")) {//check if the book was returned
                        available1++;
                        System.out.println("Book " + str + " Stock: " + available1);
                        String answer = book1 + " Stock: " + available1;
                        rd.sendR(answer);
                        out.println(book1);
                        out.println(available1);
                }
                if (str.equals(book2 + "returned")) {//check if the book was returned
                        available2++;
                        System.out.println("Book " + str + " Stock: " + available2);
                        String answer = book2 + " Stock: " + available2;
                        rd.sendR(answer);
                        out.println(book2);
                        out.println(available2);
                }
            }
        } catch (IOException e) {
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
            }
        }
    }
}

    enter code here

public class LibrarySrv {
    static final int PORT = 9090;

    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Server Started");
        Readers rd = new Readers();
        try {
            while (true) {
                // Blocks until a connection occurs:
                Socket socket = s.accept();
                try {
                    new ServeOneReader(socket, rd);
                } catch (IOException e) {
                    // If it fails, close the socket,
                    // otherwise the thread will close it:
                    socket.close();
                }
            }
        } finally {
            s.close();
        }
    }
}

客户端

package Server;

import java.net.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import javax.swing.*;

import MyPackige.Books;

public class Reader {
    BufferedReader in;
    PrintWriter out;
    InetAddress addr;
    Socket socket;
    Gui g;

    Reader(JFrame frame) {
        g = new Gui(frame);
    }

    class Gui {

        JPanel panelChB, panelText, panelStock;
        private JLabel title, bookTitle, bookTitle1, stock1, stock2;
        private JButton getBook, returnBook;
        private JCheckBox ch1, ch2;
        boolean haveBook1 = false;
        boolean haveBook2 = false;
        String book1 = "The cat in the had";
        String book2 = "Harry Potter";

        String stockFB=Integer.toString(ServeOneReader.available1);//Stock first book and Stock second book must be equal to the current variable availabel1/2 in Server but it is always 3
        String stockSB =Integer.toString(ServeOneReader.available2); 


        private void updateStockDisplay() { // update the frame after every stock changes
            stock1.setText("Stock: " + stockFB);
            stock2.setText("Stock: " + stockSB);

        }


        Gui(JFrame frame) {
            frame.setSize(400, 150);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setTitle("Books");
            frame.setResizable(false);
            frame.setLayout(new BorderLayout());
            frame.setVisible(true);


            panelChB = new JPanel();
            panelChB.setLayout(new BoxLayout(panelChB, BoxLayout.Y_AXIS));

            ch1 = new JCheckBox();
            ch2 = new JCheckBox();
            getBook = new JButton("Borrow");
            getBook.addActionListener(new SrvL());
            (new Rcv()).start();
            returnBook = new JButton("Return");
            returnBook.addActionListener(new SrvL1());

            panelChB.add(ch1);
            panelChB.add(ch2);
            panelChB.add(getBook);
            panelChB.add(returnBook);

            panelText = new JPanel();
            panelText.setLayout(new BoxLayout(panelText, BoxLayout.Y_AXIS));
            bookTitle = new JLabel("The cat in the had");
            bookTitle1 = new JLabel("Harry Potter");
            panelText.add(bookTitle);
            panelText.add(bookTitle1);

            panelStock = new JPanel();
            panelStock.setLayout(new BoxLayout(panelStock, BoxLayout.Y_AXIS));
            stock1 = new JLabel();
            stock2 = new JLabel();
            updateStockDisplay();
            panelStock.add(stock1);
            panelStock.add(stock2);

            frame.add(panelChB, BorderLayout.WEST);
            frame.add(panelText, BorderLayout.CENTER);
            frame.add(panelStock, BorderLayout.EAST);




        }



        class SrvL implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if (ch1.isSelected() || ch2.isSelected()) { //check if a book is selected
                    if (ch1.isSelected() && haveBook1==false) {// check if book 1 is selected
                        String infoMessage = "Book \"" + book1 + "\" borrowed";
                        JOptionPane.showMessageDialog(null, infoMessage,
                                "Message: ", JOptionPane.INFORMATION_MESSAGE);
                        out.println(book1 + "borrow");//send to the server suffix "borrow" after book's name to indicate the stock has to be decrease
                        haveBook1 = true;//the client can't borrow the same book anymore 

                    }
                    if (ch2.isSelected()  && haveBook2==false) {
                        String infoMessage = "Book \"" + book2 + " \" borrowed";
                        JOptionPane.showMessageDialog(null, infoMessage,
                                "Message: ", JOptionPane.INFORMATION_MESSAGE);
                        out.println(book2 + "borrow");
                        haveBook2 = true;
                    }
                } else {
                    String infoMessage = "No book selected";
                    JOptionPane.showMessageDialog(null, infoMessage,
                            "Message: ", JOptionPane.INFORMATION_MESSAGE);
                }
            }

        }

        class SrvL1 implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                if (ch1.isSelected() || ch2.isSelected()) {
                    if (ch1.isSelected() && haveBook1==true) {
                        String infoMessage = "Book \"" + book1
                                + " \"  returned";
                        JOptionPane.showMessageDialog(null, infoMessage,
                                "Message: ", JOptionPane.INFORMATION_MESSAGE);
                        out.println(book1 + "returned");
                        haveBook1 = false;

                    }
                    if (ch2.isSelected() && haveBook2==true) {

                        String infoMessage = "Book \"" + book2
                                + " \"  returned";
                        JOptionPane.showMessageDialog(null, infoMessage,
                                "Message: ", JOptionPane.INFORMATION_MESSAGE);
                        out.println(book2 + "returned");
                        haveBook2 = false;
                    }
                } else {
                    String infoMessage = "No book selected";
                    JOptionPane.showMessageDialog(null, infoMessage,
                            "Message: ", JOptionPane.INFORMATION_MESSAGE);
                }

            }

        }

        //Receive data from the server 

        class Rcv extends Thread {
            public void run() {
                for (;;) {
                    try {
                        sleep(400);
                    } catch (InterruptedException e) {
                    }
                    try {
                        String infoMessage = in.readLine();
                        JOptionPane.showMessageDialog(null, infoMessage,
                                "Message: ", JOptionPane.INFORMATION_MESSAGE);
                        String stock=in.readLine();//Server sends book's name and current stock
                        if(stock.contains(book1)){//check which book it comes
                            stockFB = in.readLine();//Server sends only current stock
                            updateStockDisplay();
                        }
                        if(stock.contains(book2)){
                            stockSB = in.readLine();
                            updateStockDisplay();
                        }

                    } catch (IOException e1) {
                        break;
                    }
                }
                System.out.println(" closing reading thread...");
                try {
                    socket.close();
                } catch (Exception expt) {
                    System.out.println(expt);
                }
                System.exit(0);
            }
        }


    }



    public void init() throws IOException {
        try {
            String server = "192.0.0.0";
            InetAddress addr = InetAddress.getByName(server);
            System.out.println("addr = " + addr);
            socket = new Socket(addr, LibrarySrv.PORT);
            System.out.println("socket = " + socket);
            // BufferedReader sin = new BufferedReader(
            // new InputStreamReader(System.in));
            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            // Output is automatically flushed
            // by PrintWriter:
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream())), true);

        } catch (Exception e) {
            System.out.println("exception: " + e);
            System.out.println("closing...");
            socket.close();
        }
    }

    public static void main(String[] args) throws IOException {
        JFrame frame = new JFrame();
        frame.setVisible(true);
        Reader rd = new Reader(frame);
        rd.init();

    }
}

2 个答案:

答案 0 :(得分:0)

当您启动客户端时,向服务器发送消息以获取Book Stock上的当前信息。

在服务器中,您已经在侦听不同类型的消息,让它再处理一条消息 - GetStockInfo。然后,您可以将存储在服务器上的书籍名称发送给客户端。

这可以解决您的问题。

答案 1 :(得分:0)

使用需要在客户端和服务器之间发送的操作代码,然后再传回任何数据。类推。

例如:

  • CLIENT_ADDED
  • CLIENT_REMOVED
  • SERVER_STARTED
  • SERVER_STOPPED
  • BOOK_BORROWED
  • BOOK_RETURNED

等...

在客户端和服务器之间设置通信协议。

检查新添加的客户的库存数据需要遵循的步骤:

  • 每当添加新客户端时,只需向服务器发送操作代码CLIENT_ADDED
  • 服务器将库存信息发回客户
  • 客户将收到库存数据并更新其用户界面。

每种类型的操作代码都遵循相同的步骤。

根据您的要求,您可以在代码中进行修改:

<强> ServerOneReader:

public void run() {
    try {
        while (true) {
            String str = in.readLine();// client sends suffix "borrowed" or "returned" after
                                       // book's name
            if(str.equals("client_added")){
                String answer1 = book1 + " Stock: " + available1;
                rd.sendR(answer);
                String answer2 = book2 + " Stock: " + available2;
                rd.sendR(answer2);
            }
            if (str.equals(book1 + "borrow")) {// check if the book was borrowed
                available1--;
            ...
相关问题