简体   繁体   English

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

[英]Socket Server Client Thread, Java

I was asking before this Question... 我在这个问题之前问过...

I want to test the TCP Socket Behaviour in my Network, beacuse I need to test my Java Applications... 我想测试网络中的TCP套接字行为,因为我需要测试Java应用程序...

I created a Server Client Model Example, using Threads... 我使用线程创建了服务器客户端模型示例。

Here the ConsumerServer 这里的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;
    }
  };

Here the ProducerClient 这里的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;
    }
  };

I want to remove the indicated block code, but when I remove.. My Test doesn't work properly. 我想删除指示的阻止代码,但是当我删除时..我的测试无法正常工作。

Here the Class using before Classes 这里的班级使用之前的班级

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);
    });
  }

}

Question: 题:

What is the reason, why I remove the indicate snippet code (in ProducerClient), my Single App doesn't work? 是什么原因,为什么我删除了指示代码段代码(在ProducerClient中),但我的Single App无法正常工作?

The reason is exactly what I told you in your other question. 原因正好是我在另一个问题中告诉您的内容。 bProducerReady needs to be volatile , as you are reading and writing it from different threads. bProducerReady必须是volatile ,因为您正在从不同的线程读取和写入它。 Your strange delay code accomplishes the same memory flush just via elapse of time. 您奇怪的延迟代码只是通过时间来完成相同的内存刷新。

NB It does not need to be static . 注意:它不必是static

Why you reposted this answered question remains a mystery. 为什么您重新发布这个已回答的问题仍然是个谜。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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