【问题标题】:Exampels on a Server-Client-Chat applikation on JAVA [closed]JAVA上的服务器-客户端-聊天应用程序示例[关闭]
【发布时间】:2015-04-08 14:42:28
【问题描述】:

长期以来,我一直在“搜索”服务器-客户端-聊天应用程序的示例,但我无法真正理解它们。他们中的许多人正在使用一个类并从中创建 GUI,我不想直接从中复制。许多示例并没有真正解释您如何将消息从客户端发送到服务器,然后将消息发送到所有其他客户端。

我正在使用 NetBeans,我想知道是否有一些好的教程或示例可以帮助我解决这个问题?

【问题讨论】:

  • 提取所需代码并将其放入 App.java 的main。此外,这不是寻求教程或示例的网站,而是特定编程问题的网站。

标签: java netbeans client chat server


【解决方案1】:

这是我刚刚制作的一个超级简单的内容,其中包含一些正在发生的事情。连接到服务器的客户端可以键入服务器将打印出的消息。这不是聊天程序,因为服务器接收消息,客户端发送消息。但希望你能更好地理解它:)

服务器:

    import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class Main {

    public static DataInputStream in;
    public static DataOutputStream out;

    public static void main(String[] args) throws IOException {


    int port = 4444;
    ServerSocket server = null;
    Socket clientSocket = null;

    try {

    //start listening on port
    server = new ServerSocket(port);

    System.out.println("Listening on port: " + port);

    //Accept client
    clientSocket = server.accept();

    System.out.println("client Connected!");

    //initialize streams so we can send message
    in = new DataInputStream(clientSocket.getInputStream());
    out = new DataOutputStream(clientSocket.getOutputStream());

    String message = null;

        while (true) {
            // as soon as a message is being received, print it out!
            message = in.readUTF();
            System.out.println(message);
        }

    }
    catch (IOException e){
        e.printStackTrace();
        if (!server.isClosed()){server.close();}
        if (!clientSocket.isClosed()){clientSocket.close();}
    }

    }

}

客户:

    import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class Main  
{
   public static void main(String[] args) throws IOException {

       //declare a scanner so we can write a message
       Scanner keyboard = new Scanner(System.in);


       // localhost ip
       String ip = "127.0.0.1";
       int port = 4444;
       Socket socket = null;

       try {

       //connect
       socket = new Socket(ip, port);

       //initialize streams
       DataInputStream in = new DataInputStream(socket.getInputStream());
       DataOutputStream out = new DataOutputStream(socket.getOutputStream());


       while (true){
           System.out.print("\nMessage to server: ");
           //Write a message :)
           String message = keyboard.nextLine();
           //Send it to the server which will just print it out
           out.writeUTF(message);
       }

       }
       catch (IOException e){
           e.printStackTrace();
            if (!socket.isClosed()){socket.close();}
       }
   }
}

【讨论】:

  • 谢谢你的例子 :) 一个问题是如果我运行 2 个客户端实例,他们能听到对方的声音吗?这意味着如果我先运行 client1 然后再运行 client2,client1 会听到 client2 发送到服务器的内容吗?
  • 不客气,对不起,这个服务器只需要一个客户端,如果一个服务器要处理多个客户端,那么你应该使用多线程。
  • 是的,我一直在看。创建客户端类的对象并将它们作为线程运行。但我不知道如何让他们在服务器上互相监听。
  • 你要我发布一个简单的多线程服务器吗?
  • 如果没有问题,我会在一个小时内准备好;)
【解决方案2】:

多线程程序来了:)服务器有两个类,客户端有一个。希望你喜欢!

服务器主类:

    import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class Main {

    public static void main(String[] args) throws IOException {
        int MAXCLIENTS = 20;
        int port = 4444;
        ServerSocket server = null;
        Socket clientSocket = null;
        // An array of clientsConnected instances
        ClientThread[] clientsConnected = new ClientThread[MAXCLIENTS];

        try {
            server = new ServerSocket(port);
            System.out.println("listening on port: " + port);
        } catch (IOException e) {// TODO Auto-generated catch block
            e.printStackTrace();

        }

        while (true) {
            try {
                clientSocket = server.accept();

            } catch (IOException e) {
                e.printStackTrace();
                if (!server.isClosed()){server.close();}
                if (!clientSocket.isClosed()){clientSocket.close();}
            }

            System.out.println("Client connected!");

            for (int c = 0; c < clientsConnected.length; c++){
                if (clientsConnected[c] == null){
                    // if it is empty ( null) then start a new Thread, and pass the socket and the object of itself as parameter
                    (clientsConnected[c] = new ClientThread(clientSocket, clientsConnected)).start();
                    break; // have to break, else it will start 20 threads when the first client connects :P
                }
            }
        }

    }



}

服务器客户端类:

    import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;


public class ClientThread extends Thread{

    private ClientThread[] clientsConnected;
    private Socket socket = null;
    private DataInputStream in = null;
    private DataOutputStream out = null;
    private String clientName = null;

    //Constructor
     public ClientThread(Socket socket, ClientThread[] clientsConnected){
        this.socket = socket;
        this.clientsConnected = clientsConnected;
    }

    public void run(){
        try {
            // Streams :)
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());

            String message = null;

            clientName = in.readUTF();

            while (true){
                message = in.readUTF();

                for (int c = 0; c < clientsConnected.length; c++){
                    if (clientsConnected[c]!= null && clientsConnected[c].clientName != this.clientName){ //dont send message to your self ;)
                        clientsConnected[c].sendMessage(message, clientName); // loops through all the list and calls the objects sendMessage method.
                    }
                }

            }

        } catch (IOException e) {
            System.out.println("Client disconnected!");
            this.clientsConnected = null;
        }
    }
    // Every instance of this class ( the client ) will have this method.
    private void sendMessage(String mess, String name){
        try {
            out.writeUTF(name + " says: " + mess);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

最后是客户:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class Main  
{
   public static void main(String[] args) throws IOException {

       Main m = new Main();
       m.connect();
   }

   public void connect() throws IOException{
     //declare a scanner so we can write a message
       Scanner keyboard = new Scanner(System.in);


       // localhost ip
       String ip = "127.0.0.1";
       int port = 4444;
       Socket socket = null;

       System.out.print("Enter your name: ");
       String name = keyboard.nextLine();

       try {

       //connect
       socket = new Socket(ip, port);

       //initialize streams
       DataInputStream in = new DataInputStream(socket.getInputStream());
       DataOutputStream out = new DataOutputStream(socket.getOutputStream());

       //start a thread which will start listening for messages
       new ReceiveMessage(in).start();

       // send the name to the server!
       out.writeUTF(name);

       while (true){
           //Write messages :)
           String message = keyboard.nextLine();
           out.writeUTF(message);
       }

       }
       catch (IOException e){
           e.printStackTrace();
            if (!socket.isClosed()){socket.close();}
       }
   }

   class ReceiveMessage extends Thread{

       DataInputStream in;

       ReceiveMessage(DataInputStream in){
           this.in = in;
       }

       public void run(){
           String message;
           while (true){
               try {
                    message = in.readUTF();
                    System.out.println(message);

                } catch (IOException e) {
                e.printStackTrace();
                }

           }
       }

   }

}

我在eclipse中运行服务器,并从CMD启动了两个客户端,如下所示:

【讨论】:

  • 非常感谢!!希望我能对此有更多了解,以及它如何与多线程一起工作!非常感谢您花时间做这件事。我会做这个,然后尝试实现它的 GUI!再次感谢,你摇滚!!
  • 听起来不错!欢迎你:)
  • 我试图找到一种发送 PM 的方法,但我找不到方法,所以我不得不在这里询问。在第一个类服务器中(称为 main) 在 for 循环中检查数组中是否有客户端,如果没有,则只需创建一个。每次接受套接字时,您不应该在列表中创建并添加一个客户端吗?因为在我看来服务器只能接受一个客户端。
  • @Bojje 如您所见,首先创建了 serversocket,然后有一个 while 循环。所以当有人连接时,它会跳到for循环并检查数组中是否有一个空元素。如果它为空,则正在创建类 ClientThread 的新实例,然后将其存储在数组“clientsConnected[c]”中,然后启动它。都在同一行:)。之后,由于这一切都在一个while循环中,它会回到while循环的开头,即clientSocket = serverSocket.accept(); .这将继续下去:)
  • 是的,这也是我不太明白的事情。它在一个while循环中,所以它不应该一直运行,而它是真的吗?如果 serversocket 接受新的套接字,为什么会跳转到 for 循环?当第二个客户被接受时,它是如何工作的?那么for循环什么都不做?编辑哦,没关系...我只是看错了。对不起
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
相关资源
最近更新 更多