简体   繁体   中英

Communication between Java server and Client

I'm brand new to server concept in java. I've set up a very simple server (most of it was copied from he net) and I would like it to send at what "status" it is, but I would like it to send it only once. Here is my code it might be more clear.

Server:

    package components;

import java.io.DataInputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;

public class mainServer {

  // The server socket.
  private static ServerSocket serverSocket = null;
  // The client socket.
  private static Socket clientSocket = null;

  // This chat server can accept up to maxClientsCount clients' connections.
  private static final int maxClientsCount = 3;
  private static final clientThread[] threads = new clientThread[maxClientsCount];

  public static void main(String args[]) {

    // The default port number.
    int portNumber = 3333;
    if (args.length < 1) {
      System.out
          .println("Usage: java MultiThreadChatServer <portNumber>\n"
              + "Now using port number=" + portNumber);
    } else {
      portNumber = Integer.valueOf(args[0]).intValue();
    }

    /*
     * Open a server socket on the portNumber (default 2222). Note that we can
     * not choose a port less than 1023 if we are not privileged users (root).
     */
    try {
      serverSocket = new ServerSocket(portNumber);
    } catch (IOException e) {
      System.out.println(e);
    }

    /*
     * Create a client socket for each connection and pass it to a new client
     * thread.
     */
    while (true) {
      try {
        clientSocket = serverSocket.accept();
        int i = 0;
        for (i = 0; i < maxClientsCount; i++) {
          if (threads[i] == null) {
            (threads[i] = new clientThread(clientSocket, threads)).start();
            break;
          }
        }
        if (i == maxClientsCount) {
          PrintStream os = new PrintStream(clientSocket.getOutputStream());
          os.println("Server too busy. Try later.");
          os.close();
          clientSocket.close();
        }
      } catch (IOException e) {
        System.out.println(e);
      }
    }
  }
}

/*
 * The chat client thread. This client thread opens the input and the output
 * streams for a particular client, ask the client's name, informs all the
 * clients connected to the server about the fact that a new client has joined
 * the chat room, and as long as it receive data, echos that data back to all
 * other clients. When a client leaves the chat room this thread informs also
 * all the clients about that and terminates.
 */
class clientThread extends Thread {

  private DataInputStream is = null;
  private PrintStream os = null;
  private Socket clientSocket = null;
  private final clientThread[] threads;
  private int maxClientsCount;

  public clientThread(Socket clientSocket, clientThread[] threads) {
    this.clientSocket = clientSocket;
    this.threads = threads;
    maxClientsCount = threads.length;
  }

  public void run() {
    int maxClientsCount = this.maxClientsCount;
    clientThread[] threads = this.threads;

    try {
      /*
       * Create input and output streams for this client.
       */
      is = new DataInputStream(clientSocket.getInputStream());
      os = new PrintStream(clientSocket.getOutputStream());
      os.println("Enter your name.");

      while (true) {
        String line = is.readLine();
        if (line.startsWith("/quit")) {
            break;
        }
        if (line.startsWith("Home")) {
            os.println("Server in Home mode");
        }
        if (line.startsWith("Search / Modify")){
            System.out.println("Server in search and modify mo");
        }
      }
      for (int i = 0; i < maxClientsCount; i++) {
        if (threads[i] != null && threads[i] != this) {
          threads[i].os.println("*** The user "
              + " is leaving the chat room !!! ***");
        }
      }
      os.println("*** Bye " + " ***");

      /*
       * Clean up. Set the current thread variable to null so that a new client
       * could be accepted by the server.
       */
      for (int i = 0; i < maxClientsCount; i++) {
        if (threads[i] == this) {
          threads[i] = null;
        }
      }

      /*
       * Close the output stream, close the input stream, close the socket.
       */
      is.close();
      os.close();
      clientSocket.close();
    } catch (IOException e) {
    }
  }
}

Main: So at the moment its constantly sending through the output stream the word home, and then the server sends back the string "The server is in Home status" which is then printed. how do I get it to send only once, this would be useful for me to be able to detect which button is pressed on my gui and send a command to the server when it is.

package components;

//Import all libraries
import java.awt.EventQueue;

public class MainFrame implements Runnable {
    //declare Jpanel
    private static JFrame frmHome;

    // The client socket
    private static Socket clientSocket = null;
    // The output stream
    private static PrintStream os = null;
    // The input stream
    private static DataInputStream is = null;
    private static BufferedReader inputLine = null;
    private static boolean closed = false;

    public static void main(String[] args){
        // The default port.
        int portNumber = 3333;
        // The default host.
        String host = "localhost";

          System.out
              .println("Usage: java MultiThreadChatClient <host> <portNumber>\n"
                  + "Now using host=" + host + ", portNumber=" + portNumber);
        /*
         * Open a socket on a given host and port. Open input and output streams.
         */
        try {
          clientSocket = new Socket(host, portNumber);
          inputLine = new BufferedReader(new InputStreamReader(System.in));
          os = new PrintStream(clientSocket.getOutputStream());
          is = new DataInputStream(clientSocket.getInputStream());
        } catch (UnknownHostException e) {
          System.err.println("Don't know about host " + host);
        } catch (IOException e) {
          System.err.println("Couldn't get I/O for the connection to the host "
              + host);
        }

        /*
         * If everything has been initialized then we want to write some data to the
         * socket we have opened a connection to on the port portNumber.
         */
        if (clientSocket != null && os != null && is != null) {
          try {

            /* Create a thread to read from the server. */
            new Thread(new MainFrame()).start();
            while (!closed) {
              os.println("Home");
            }
            /*
             * Close the output stream, close the input stream, close the socket.
             */
            os.close();
            is.close();
            clientSocket.close();
          } catch (IOException e) {
            System.err.println("IOException:  " + e);
          }
        }
      }

      /*
       * Create a thread to read from the server. (non-Javadoc)
       * 
       * @see java.lang.Runnable#run()
       */
      public void run() {
        /*
         * Keep on reading from the socket till we receive "Bye" from the
         * server. Once we received that then we want to break.
         */
          MainFrame window = new MainFrame();
          MainFrame.frmHome.setVisible(true);
        String responseLine;
        try {
          while ((responseLine = is.readLine()) != null) {
            System.out.println(responseLine);
            if (responseLine.indexOf("*** Bye") != -1)
              break;
          }
          closed = true;
        } catch (IOException e) {
          System.err.println("IOException:  " + e);
        }
        }

    public MainFrame() {
        initialize();
    }

    //function to make window visible
    void setVisible() {
        main(null);
    }

    private void initialize() {
        //Initialise Main window with 3 options.
        frmHome = new JFrame();
        frmHome.setTitle("Home");
        frmHome.setBounds(100, 100, 300, 372);
        frmHome.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmHome.getContentPane().setLayout(null);
        frmHome.setResizable(false);

        JLabel lblWelcomeToSrs = new JLabel("Welcome to SRS");
        lblWelcomeToSrs.setFont(new Font("Tahoma", Font.PLAIN, 14));
        lblWelcomeToSrs.setBounds(86, 183, 112, 14);
        frmHome.getContentPane().add(lblWelcomeToSrs);

        //initialise all buttons and labels of window.
        JButton btnAdStu = new JButton("Add a student");
        btnAdStu.setBounds(10, 207, 126, 23);
        btnAdStu.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                AddStudentFrame adus;
                try {
                    adus = new AddStudentFrame();
                    adus.setVisible();
                    frmHome.setVisible(false);
                } catch (ParseException e) {
                    e.printStackTrace();
                }

            }
        });
        frmHome.getContentPane().add(btnAdStu);

        JButton btnCheckStud = new JButton("Search / Modify");
        btnCheckStud.setBounds(146, 207, 127, 23);
        btnCheckStud.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                SearchFrame searchFrame;
                searchFrame = new SearchFrame();
                searchFrame.setVisible();
            }
        });
        frmHome.getContentPane().add(btnCheckStud);

        JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setBounds(0, 0, 0, 0);
        frmHome.getContentPane().add(lblNewLabel);

        JLabel lblCreatedByRmi = new JLabel("Created by R\u00E9mi Tuyaerts");
        lblCreatedByRmi.setBounds(147, 318, 184, 14);
        frmHome.getContentPane().add(lblCreatedByRmi);  

        JButton btnNewButton = new JButton("Complete List of Students");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                CompleteListFrame studentList = new CompleteListFrame();
                frmHome.setVisible(false);
                studentList.setVisible();
            }
        });
        btnNewButton.setBounds(52, 241, 184, 23);
        frmHome.getContentPane().add(btnNewButton);

        // Button to set up the database
        JButton btnFillInDatabase = new JButton("Fill in database");
        btnFillInDatabase.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                StudentStoring.student1();
                StudentStoring.student2();
                StudentStoring.student3();
                StudentStoring.student4();
            }
        });
        btnFillInDatabase.setBounds(80, 276, 126, 23);
        frmHome.getContentPane().add(btnFillInDatabase);

        // wonderful pictures of his excellence design by Yasser
        JLabel lblNewLabel_1 = new JLabel("");
        Image img = new ImageIcon(frmHome.getClass().getResource("/michaelchung.jpg")).getImage();
        lblNewLabel_1.setIcon(new ImageIcon(img));
        lblNewLabel_1.setBounds(80, 11, 120, 148);
        frmHome.getContentPane().add(lblNewLabel_1);
    }
}

You'll have to decide if you want to use a single connection to transfer multiple messages back and forth, or if you want to establish a new connection for every message.

To keep a single connection, just open the socket (on the client side) and keep it somewhere. Don't close() it until you actually don't need the connection any more.

If you want to use one connection per message, effectively signalling the end of the message via close() , you should use setSoLinger() on that side which is closing the connection. This will give the other end some time to read any pending data, detect the end of the data, and prepare for the end of the conversation without running into the "socket closed" exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM