套接字服务器客户端线程,Java

时间:2016-12-20 17:44:28

标签: java multithreading sockets tcp serversocket

我在这个问题之前问过......

我想在我的网络中测试TCP套接字行为,因为我需要测试我的Java应用程序......

我使用Threads ...

创建了一个Server Client Model Example

这里是ConsumerServer

  public class ConsumerServer extends Thread {
    private ServerSocket SrvrScktConsumer;
    Socket clientSocket = null;
    private boolean isConsumerRunning = false;

    public ConsumerServer(int ConsPort) {
      try {
        SrvrScktConsumer = new ServerSocket(ConsPort);
        System.out.println(NL + "ConsumerServer Listening on port number: " + ConsPort);
      } catch (IOException e) { }
    }

    @Override public void run() {
      try {
        clientSocket = SrvrScktConsumer.accept();
        InputStream input;
        byte[] innerBytes = new byte[1024];
        try {
          input  = clientSocket.getInputStream();
          Integer iRemotePort = clientSocket.getPort();
          String sRemoteHost = clientSocket.getInetAddress().getHostAddress();
          System.out.println("ConsumerServer: Remote Connection\n\tPort:" + iRemotePort+ " Host:" + sRemoteHost);
          isConsumerRunning = true;
          while (isConsumerRunning) {
            try {
              byte[] incomingBytes = Arrays.copyOf(innerBytes, input.read(innerBytes));
              jtaMessages.append(NL + "Consumer GET " + new String(incomingBytes));
              jtfLastReceived.setText(new String(incomingBytes));
            } catch (IOException | NegativeArraySizeException | IndexOutOfBoundsException e) {
              isConsumerRunning = false;
            }
          }
          System.out.println(NL + "ConsumerClient closing from Host " + sRemoteHost + " Port " + iRemotePort);
          try {  if (input != null) input.close(); } catch (IOException e) { }
        } catch (IOException e) {
          System.out.println(NL + "Error Creating ConsumerClient\n\t:" + e.toString());
        }
      } catch (IOException | NullPointerException e) {
          System.out.println(NL + "ConsumerServer Stopped: " + e.toString()) ;
      }
      System.out.println(NL + "Exiting ConsumerServer...");
    }

    public void stopServer() {
      try {
        SrvrScktConsumer.close();
      } catch (IOException | NullPointerException e) { }
      try {
        clientSocket.close();
      } catch (IOException | NullPointerException e) { }
      isConsumerRunning = false;
    }
  };

这里是ProducerClient

  public class ProducerClient extends Thread {
    private Socket clientSocket = null;
    private OutputStream output = null;
    private boolean isProducerRunning = false;

    public ProducerClient(String ConsHost , int ConsPort) {
      try {
        clientSocket = new Socket(ConsHost, ConsPort);
        output = clientSocket.getOutputStream();
        System.out.println(NL + "ProducerClient Connected to port number: " + ConsPort);
      }
      catch (IOException e) { }
    }

    @Override public void run() {
      if (!(clientSocket == null)) {
        Integer iLocalPort = clientSocket.getLocalPort();
        String sLocalHost = clientSocket.getLocalAddress().getHostAddress();
        System.out.println("ConsumerServer: Local Connection\n\tPort:" + iLocalPort+ " Host:" + sLocalHost);
        int ctrlPrintOut = 0, ctrlPrintIn = 0;
        isProducerRunning = true;
        while (isProducerRunning) {
          try {
            if (bProducerReady) {
              bProducerReady = false;
              output.write(jtfSendMessage.getText().getBytes());
              jtaMessages.append(NL + "Producer PUT " + jtfSendMessage.getText());
              jtfSendMessage.setText("");
            }
//            // Ini Code Block to delete
//            else {
//              try {
//                Thread.sleep(1);
//              } catch (InterruptedException ex) { }
//              if (ctrlPrintOut == 1000000 /*Integer.MAX_VALUE*/) {
//                if (ctrlPrintIn == 2) {
//                  System.out.println("ProducerClient Waiting!");
//                  ctrlPrintIn = 0;
//                }
//                ctrlPrintIn++; ctrlPrintOut = 0;
//              }
//              ctrlPrintOut++;
//            }
//            // End Code Block to delete
          } catch (IOException e) {
            System.out.println("ProducerClient: " + e.toString());
            isProducerRunning = false;
          }
        }
        try { output.close(); } catch (IOException e) { }
        try { clientSocket.close(); } catch (IOException e) { }
        System.out.println(NL + "Exiting ProducerClient...");
      }
    }

    public void stopClient() {
      try {
        clientSocket.close();
      } catch (IOException | NullPointerException e) { }
      isProducerRunning = false;
    }
  };

我想删除指示的块代码,但是当我删除..我的测试无法正常工作。

这里使用类之前的类

public class ClientServerShort extends JFrame {

  private JButton jbSendMessage = new JButton("Send Message");
  private JLabel jlLastReceived = new JLabel("Last Received");
  private JTextArea jtaMessages = new JTextArea(5,20);
  private JScrollPane jspMessages = new JScrollPane(jtaMessages);
  private JToggleButton jtbConsumer = new JToggleButton("Launch Consumer Server");
  private JToggleButton jtbProducer = new JToggleButton("Launch Producer Client");
  private JTextField jtfLastReceived = new JTextField();
  private JTextField jtfSendMessage = new JTextField();

  static boolean bProducerReady = false;
  static final String NL = System.getProperty("line.separator");
  ConsumerServer thrdConsumerServer = null;
  ProducerClient thrdProducerClient = null;

  public ClientServerShort() {
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    jbSendMessage.addActionListener((ActionEvent evt) -> {
      if (!jtfSendMessage.getText().isEmpty()) {
        bProducerReady = true;
      }
    });

    jlLastReceived.setBorder(BorderFactory.createEtchedBorder());
    jlLastReceived.setHorizontalAlignment(SwingConstants.CENTER);

    jtbConsumer.addActionListener((ActionEvent evt) -> {
      if (jtbConsumer.isSelected()) {
        if (thrdConsumerServer == null) {
          thrdConsumerServer = new ConsumerServer(1027);
          thrdConsumerServer.start();
        }
      } else {
        if (thrdConsumerServer != null) {
          thrdConsumerServer.stopServer();
          thrdConsumerServer = null;
        }
      }
    });
    jtbProducer.addActionListener((ActionEvent evt) -> {
      if (jtbProducer.isSelected()) {
        if (thrdProducerClient == null) {
          thrdProducerClient = new ProducerClient("192.168.0.49", 1027);
          thrdProducerClient.start();
        }
      } else {
        if (thrdProducerClient != null) {
          thrdProducerClient.stopClient();
          thrdProducerClient = null;
        }
      }
    });

    jtfLastReceived.setEditable(false);

    JPanel jpMessagesUp = new JPanel();
    jpMessagesUp.setLayout(new GridLayout(2, 2, 6, 6));
    jpMessagesUp.add(jbSendMessage);
    jpMessagesUp.add(jtfSendMessage);
    jpMessagesUp.add(jlLastReceived);
    jpMessagesUp.add(jtfLastReceived);

    getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
    add(jtbProducer);
    add(jtbConsumer);
    add(jpMessagesUp);
    add(jspMessages);
    pack();
  }

  public static void main(String args[]) {
    EventQueue.invokeLater(() -> {
      new ClientServerShort().setVisible(true);
    });
  }

}

问题:

是什么原因,为什么我删除了指示代码段(在ProducerClient中),我的单个应用程序不起作用?

1 个答案:

答案 0 :(得分:0)

原因正是我在你的另一个问题中告诉你的。 bProducerReady需要volatile,因为您正在从不同的线程中读取和写入它。你的奇怪的延迟代码只是经过一段时间才能完成相同的内存刷新。

注意它不需要是static

为什么你转发这个已回答的问题仍然是一个谜。