3

I am currently developing a chat application which is quite basic overall, however I am encountering problems when receiving strings from both the client and the server side. I am using a thread to passively listen on the socket for incoming messages, which is where I suspect the problem to be. Am I doing this the right way?

Source: Code for sending strings:

send.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            messageBuffer = message.getText();
            out.println(messageBuffer);
            chat.append(username + ": " + messageBuffer + "\n");
            message.setText("");
        }
    });

I then have this which passively listens (problem is probably here):

public void run(){
    while(true){
        try {
               messageBufferIn = in.readLine();
               System.out.println(in.readLine());
               chat.append(recipient + ": " + messageBufferIn + "\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Im also calling the thread using this:

public static void startChatting(){
    try {
        Thread.sleep(10);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

Thanks for any help you can provide, Im still new to threads overall so my mistake might be quite mediocre.

Edit: The problem is when I try sending a message to the receiver, nothing comes through, I can confirm that they are connected. In fact the System.out.println(in.readLine()); doesnt come through at all, not even a "null" output.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Andrei0427
  • 573
  • 3
  • 6
  • 18
  • And the problem is what exactly...? – user1329572 Aug 23 '12 at 11:20
  • Perhaps [this](http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html) will help.. – user1329572 Aug 23 '12 at 11:30
  • @user1329572 I have been told using while loops when listening on a socket for data is a bad CPU clog. Is this correct, or is this the only way? – Andrei0427 Aug 23 '12 at 11:34
  • Most of the reader's will actually block (or stop) thread execution until some input is received. So in the background, the reader is doing what you're redoing by telling the thread to sleep (meaning you really don't need to do it). – Nick Rippe Aug 24 '12 at 02:55

2 Answers2

3
  1. you have got issue with Concurency in Swing, Swing GUI don't know that you running / open the Socket on Background Task,

  2. all updates to the Swing GUI must be done on EDT, otherwise nothing happened or you got a few exceptions

  3. have to wrap all updates from Background Task (in your case Runnable#Thread) to the invokeLater for Swing GUI

  4. while(true){ is endless loop put there Boolean variable instead of true, then you can to stop, start or restart whatever in your case Socket

  5. in the case that send.addActionListener(new ActionListener(){ runs only once time (if user invoked by JButtons click) then to use SwingWoker for opening Socket, SwingWorker quite good guarantee that all output should be done on EDT

  6. difference betweens Runnable#Thread and SwingWorker is that SwingWorker is designated to run only once times

mKorbel
  • 109,525
  • 20
  • 134
  • 319
2

I suspect your main problem is that you're not flushing the OutputStream. You'll want to add out.flush() after you've finished writing to it and want to send the message. For example, your ActionListener would look like this:

send.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        messageBuffer = message.getText();
        out.println(messageBuffer);
        out.flush();
        chat.append(username + ": " + messageBuffer + "\n");
        message.setText("");
    }
});

If you don't do this, your OutputStream will sit there until it's buffer's full (which will be a lot of messages).

Nick Rippe
  • 6,465
  • 14
  • 30