简体   繁体   English

我不明白为什么我的一个客户端程序不能向服务器发送多于一条消息?

[英]I don't understand why one of my client program can't send more than one message to the server?

I have created a simple server class and a simple client class.我创建了一个简单的服务器 class 和一个简单的客户端 class。 I have two client programs that connect to the server.我有两个连接到服务器的客户端程序。 The client & server class can send & receive messages.客户端和服务器 class 可以发送和接收消息。

The problem is that when both clients connect to the server, one of the clients can send multiple messages to the server whilst the other client can only send one message to the server.问题是当两个客户端都连接到服务器时,其中一个客户端可以向服务器发送多条消息,而另一个客户端只能向服务器发送一条消息。

Here is the constructor for my Server class:这是我的服务器 class 的构造函数:

   public MyServer () {
      setUpConnection ();
   }

Here is the code that connects the client to a port:以下是将客户端连接到端口的代码:

   public void setUpConnection () {
     clientOutputStreams = new ArrayList ();
     try {
       serverSocket = new ServerSocket (5000);
     while (true) {
       Socket clientSocket = serverSocket.accept ();
       printWriter = new PrintWriter (clientSocket.getOutputStream ());
       clientOutputStreams.add (printWriter);

       Thread thread = new Thread (new clientHandler (clientSocket));
       thread.start();

       System.out.println ("Client is connected to server");
     }    
    } catch (Exception e) {
       e.printStackTrace ();
    }
  }

This is the code that sends the messages received by the server to other clients:这是将服务器收到的消息发送给其他客户端的代码:

    public void tell everyone (String message) {
     Iterator outputObject = clientOutputStreams.iterator();

     while (outputObject.hasNext()) {
        try {
            PrintWriter writer = (PrintWriter) outputObject.next();
            writer.println (message);
            writer.flush ();
        } catch (Exception e) {
            e.printStackTrace ();
        }
     }
 }

This is the code that runs in a separate thread that listens for messages sent by clients:这是在单独线程中运行的代码,用于侦听客户端发送的消息:

    public class clientHandler implements Runnable {

       Socket clientSocket;

       public clientHandler (Socket socket) {
          try {
           clientSocket = socket;
           isr = new InputStreamReader (clientSocket.getInputStream());
           reader = new BufferedReader (isr); 
          } catch (Exception e) {
          e.printStackTrace ();
       }
    }

    public void run () {
        String message;

      try {
        while ((message = reader.readLine()) != null) {
            System.out.println ("I recieved message: " + message);
            tellEveryone (message);
        }  
      } catch (Exception e) {
          e.printStackTrace();
      }
     }
    }
 }

Here is the constructor for my client class:这是我的客户 class 的构造函数:

   public MyClient() {
      initComponents();
      setUpConnection ();
      Thread thread = new Thread (new recievingMessages ());
      thread.start ();
      jtaRec.setEditable (false);
      jtfSend.addFocusListener (this);
      jtfSend.requestFocus();
   }                

Here is the code that runs when the client presses the send button:这是客户端按下发送按钮时运行的代码:

private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
    try {
        writer.println (jtfSend.getText ());
        System.out.println (jtfSend.getText ());
        writer.flush ();
        System.out.println ("message has sent");
    } catch (Exception e) {
        e.printStackTrace ();
    }//CLOSE CATCH STATEMENT
    jtfSend.setText ("");
    jtfSend.requestFocus();
}                                          

Here is the code that connects the client to the server:以下是将客户端连接到服务器的代码:

public void setUpConnection () {
  try {
    socket = new Socket ("127.0.0.1", 5000);
    writer = new PrintWriter (socket.getOutputStream ());
    stream = new InputStreamReader (socket.getInputStream ());
    reader = new BufferedReader (stream);

    System.out.println ("Connection Made");
  } catch (Exception e) {
      e.printStackTrace ();
  }
}

Here is the code runs in a separate thread and listens for messages sent by the server:这是代码在单独的线程中运行并侦听服务器发送的消息:

  public class recievingMessages implements Runnable {
      public void run () {
        String message;
        try {
         while ((message = reader.readLine ()) != null) {
            jtaRec.append (message + "\n");
            System.out.println ("I recieved the message" + " " + message);
         }
        } catch (Exception e) {
           e.printStackTrace();
       }
    }
  }

I have tried finding a solution but I just don't understand why one client can only send one message whilst the other client can send multiple messages even though both programs share the same class.我已经尝试找到解决方案,但我只是不明白为什么一个客户端只能发送一条消息而另一个客户端可以发送多条消息,即使两个程序共享相同的 class。

I played a bit with your networking code and it seems to be working fine.我玩了一下你的网络代码,它似乎工作正常。

I mean, both clients have been able to send and receive multiple messages:我的意思是,两个客户端都能够发送和接收多条消息:

#### server logs ####           ### Jack logs ###           ### Gill logs ###
Starting server
Client is connected to server   Jack connected
SRV:1 received: Jack: Aa #1     SND:Jack - Jack: Aa #1
                                RCV:Jack - Jack: Aa #1
Client is connected to server   SND:Jack - Jack: Aa #2      Gill connected
SRV:1 received: Jack: Aa #2     RCV:Jack - Jack: Aa #2      RCV:Gill - Jack: Aa #2
SRV:2 received: Gill: Zz #1     RCV:Jack - Gill: Zz #1      RCV:Gill - Gill: Zz #1
                                                            SND:Gill - Gill: Zz #1
SRV:2 received: Gill: Zz #2     RCV:Jack - Gill: Zz #2      RCV:Gill - Gill: Zz #2
                                                            SND:Gill - Gill: Zz #2
SRV:1 received: Jack: Aa #3     RCV:Jack - Jack: Aa #3      RCV:Gill - Jack: Aa #3
                                SND:Jack - Jack: Aa #3
SRV:2 received: Gill: Zz #3     RCV:Jack - Gill: Zz #3      RCV:Gill - Gill: Zz #3
                                                            SND:Gill - Gill: Zz #3
SRV:2 received: Gill: Zz #4     RCV:Jack - Gill: Zz #4      RCV:Gill - Gill: Zz #4
                                                            SND:Gill - Gill: Zz #4
SRV:1 received: Jack: Aa #4     SND:Jack - Jack: Aa #4
                                RCV:Jack - Jack: Aa #4      RCV:Gill - Jack: Aa #4
SRV:2 received: Gill: Zz #5     RCV:Jack - Gill: Zz #       RCV:Gill - Gill: Zz #5
                                                            SND:Gill - Gill: Zz #5
SRV:1 received: Jack: Aa #5     SND:Jack - Jack: Aa #5
                                RCV:Jack - Jack: Aa #5

Most likely, in your case one of the clients connected too late and was unable to get entire history as this feature is not implemented at the server side.最有可能的是,在您的情况下,其中一个客户端连接得太晚并且无法获取整个历史记录,因为此功能未在服务器端实现。

Also, one of your clients might have disconnected too early and lose part of the history.此外,您的一个客户可能过早断开连接并丢失了部分历史记录。

In order to further analyze the reasons of lost messages, you may need to provide details of your UI code (how you build UI in initComponents() and run the client app).为了进一步分析丢失消息的原因,您可能需要提供您的 UI 代码的详细信息(您如何在initComponents()中构建 UI 并运行客户端应用程序)。

It could be that the UI components could fail to update if you changed them outside the GUI thread, so calling jtaRec.revalidate() may help.如果您在 GUI 线程之外更改 UI 组件可能无法更新,因此调用jtaRec.revalidate()可能会有所帮助。

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

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