如何实现多个客户端 - 服务器聊天

时间:2013-06-12 10:10:48

标签: java client-server chat java-communication-api

我有一个客户端 - 服务器通信代码。但是,我实际上希望多个客户端与服务器进行通信而不是其他客户端,我该如何实现呢?

// This is server code:

import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class ServerFile extends JFrame {
    private JTextField usertext;
    private JTextArea chatwindow;
    private ObjectOutputStream output;
    private ObjectInputStream input;
    private ServerSocket server;
    private Socket connection;

    public ServerFile() {
        super("Admin");
        usertext = new JTextField();
        usertext.setEditable(false);
        usertext.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                sendmessage(event.getActionCommand());
                usertext.setText("");
            }
        });
        add(usertext, BorderLayout.SOUTH);
        chatwindow = new JTextArea();
        add(new JScrollPane(chatwindow));
        setSize(300, 250);
        setVisible(true);
    }

    public void startrunning() {
        try {
            server = new ServerSocket(6789, 100);
            while (true) {
                try {
                    waitForConnection();
                    setupstream();
                    whilechatting();
                } catch (Exception e) {
                    System.out
                            .println("\nYou have an error in conversation with client");
                } finally {
                    closecrap();
                }
            }
        } catch (Exception e) {
            System.out.println("\nYou have an error in connecting with client");
        }
    }

    private void waitForConnection() throws IOException {

        showmessage("\nWaiting for someone to connect");
        connection = server.accept();
        showmessage("\nNow connected to "
                + connection.getInetAddress().getHostName());
    }

    private void setupstream() throws IOException {

        output = new ObjectOutputStream(connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream(connection.getInputStream());
        showmessage("\nStreams are setup");
    }

    private void whilechatting() throws IOException {

        String message = "\nYou are now connected ";
        sendmessage(message);
        ableToType(true);
        do {
            try {
                message = (String) input.readObject();
                showmessage(message);
            } catch (Exception e) {
                System.out.println("\nError in reading message");
            }
        } while (!message.equals("CLIENT-END"));
    }

    private void closecrap() {

        showmessage("\nClosing connection");
        ableToType(false);
        try {
            output.close();
            input.close();
            connection.close();
        } catch (Exception e) {
            System.out.println("\nError in closing server");

        }
    }

    private void sendmessage(String message) {

        try {
            chatwindow.append("\nSERVER: " + message);
            output.writeObject("\nSERVER: " + message);
            output.flush();
        } catch (Exception e) {
            chatwindow.append("\nError in sending message from server side");
        }
    }

    private void showmessage(final String text) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                chatwindow.append("\n" + text);
            }
        });
    }

    private void ableToType(final boolean tof) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                usertext.setEditable(tof);
            }
        });
    }

}

public class Server {
    public static void main(String args[]) {
        ServerFile server1 = new ServerFile();
        server1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        server1.startrunning();
    }
}



// and this is the client code:

import javax.swing.JFrame;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class ClientFile extends JFrame { 

    private static final long serialVersionUID = 1L;
    private JTextField usertext;
      private JTextArea chatwindow;
      private ObjectOutputStream output;
      private ObjectInputStream input;
      private String message="";
      private String serverIP;
      private ServerSocket server;
      private Socket connection;

      public ClientFile(String host)
      {   
          super("Client");
          serverIP=host;
          usertext= new JTextField();
          usertext.setEditable(false);
          usertext.addActionListener( new ActionListener(){
              public void actionPerformed(ActionEvent event){
                  sendmessage(event.getActionCommand());
                  usertext.setText("");
                }
            }
          );

          add(usertext,BorderLayout.SOUTH);
          chatwindow= new JTextArea();
          add(new JScrollPane(chatwindow));
          setSize(300,250);
          setVisible(true);
      }

      public void startrunning() {
          try {
              connecttoserver();
              setupstream();
              whilechatting();
          }
          catch(Exception e){
              System.out.println("\nYou have an error in coversation with server");
          }
          finally{
              closecrap();
          }
      }

      private void connecttoserver() throws IOException{
          showmessage("\nAttempting connection");
          connection =  new Socket(InetAddress.getByName("127.0.0.1"),6789);          
          showmessage("\nConnected to "+connection.getInetAddress().getHostName());
      }

      private void setupstream() throws IOException{
          output= new ObjectOutputStream(connection.getOutputStream());
          output.flush();
          input= new ObjectInputStream(connection.getInputStream());
          showmessage("\nStreams are good to go");
      }

      private void whilechatting()throws IOException{
          ableToType(true);
          do {
              try{
                  message = (String)input.readObject();
                  showmessage(message);
              }
              catch(Exception e){
                  System.out.println("\nError in writing message");
              }
          } while(!message.equals("SERVER - END"));
      }

      private void closecrap(){
          showmessage("\nClosing....");
          ableToType(false);
          try{
              output.close();
              input.close();
              connection.close();
          }
          catch(Exception e){
              System.out.println("\nError in closing client");
          }
      }

      private void sendmessage(String message){
          try{
              chatwindow.append("\nCLIENT: "+message);
              output.writeObject("\nCLIENT: "+message);
              output.flush();
          }
          catch(Exception e){
              chatwindow.append("\nError in sending message from client side");
          }
      }

      private void showmessage(final String m){
            SwingUtilities.invokeLater( new Runnable(){
            public void run(){
                chatwindow.append("\n"+m);
            }});
      }

      private void ableToType(final boolean tof){
          SwingUtilities.invokeLater( new Runnable(){
          public void run(){
          usertext.setEditable(tof);
         }});
      }
}

public class Client {
       public static void main(String args[])
       {
           ClientFile obj2= new ClientFile("127.0.0.1");
           obj2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           obj2.startrunning();

       }        
}

应用多线程是一个很好的解决方案,但是当我应用时,只在一个客户端和一个服务器之间建立了连接..请帮我这样做

1 个答案:

答案 0 :(得分:2)

  

应用多线程是一个很好的解决方案,但是当我应用时,只在一个客户端和一个服务器之间建立了连接..请帮我这样做

我没有通过(并因此检查)你的所有代码,但我注意到了一件事:

startrunning()函数中:

  • 创建服务器套接字
  • 在一个infine循环中:
    • 等待新连接
    • 当有新的连接呼叫setupstream()
    • 并使用whilechatting()
    • 聊天

所以在那里,您将只获得一个新连接,以便设置其流并进行聊天。你只能有一个线程服务于你的客户端,所以只有第一个到达的线程才会被服务,直到它释放线程,以便另一个线程可以连接。

你应该这样做:

  • 创建服务器套接字
  • 在一个infine循环中:
    • 等待新连接
    • 当有新连接时:
    • 为该连接创建新线程
    • 致电setupstream()
    • 并使用whilechatting()
    • 聊天

每个客户端都会产生自己的舒适线程,而主线程处于无限循环中等待新客户端。

HTH