【问题标题】:Can't properly keep track of connected clients java无法正确跟踪连接的客户端 java
【发布时间】:2015-03-17 10:04:00
【问题描述】:

我似乎不知道如何通知我的服务器类连接丢失。我的服务器代码是:

public class Server {

    static int port = 4444;
    static boolean listening = true;
    static ArrayList<Thread>Clients = new ArrayList<Thread>();
    static MatchMaker arena;

    public static void main(String[] args) {
        Initialize();
        Thread startConnections = new Thread(run());
        startConnections.start();
    }

    private static Runnable run(){
        System.out.println("(" +  new SimpleDateFormat("HH:mm:ss").format(new Date()) + ") Started listening on port: " + port);
        try(ServerSocket socket = new ServerSocket(port)){
            while(listening){
                if(Clients.size() <= 4){
                    Socket clientSocket = socket.accept();

                    MultiThread connection = new MultiThread(clientSocket, arena, );
                    Clients.add(connection);

                    System.out.println("Client connected from " + clientSocket.getRemoteSocketAddress() + " Assigned ID: " + connection.getId());
                    System.out.println("Currently connected clients(" + Clients.size() + "): ");
                    for(int i = 0; i < Clients.size(); i++)
                        System.out.println("   - " + Clients.get(i).getId());
                    connection.start();
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private static void Initialize(){
        arena = new MatchMaker();
    }

}

这里的问题是,由于此类跟踪已连接的客户端,因此我希望它在客户端丢失连接时通知它。 MultiThread 类已经具有检测丢失连接的客户端的功能方法,但是我不知道如何将该信息传递回 Server 类。我尝试将服务器类作为参数传递给 MultiThread,但它说我不能以静态方式使用“this”。

【问题讨论】:

  • 顺便说一句,在main 中,您的代码根本没有启动新线程并且已损坏。你可以直接调用run() 而不是这段代码。
  • Server 中没有代码应该处理有关断开连接的通知。

标签: java multithreading server


【解决方案1】:

您可以将它们保存在同步地图中,例如:

Map<Integer, ClientObject> connectedClients = new HashMap<Integer, ClientObject>(); //key integer will be the client id 

其他建议:

Map<String, ClientObject> connectedClients = new HashMap<String, ClientObject>(); //key String will be the client IP&userName (you decide)

【讨论】:

  • 我应该如何访问其他类中的地图?
  • 您可以创建一个单例来帮助您从中插入/获取数据。单例实际上将管理您获得的所有连接的客户端
【解决方案2】:

首先使用线程安全集合来监视客户端连接,因此请替换以下内容 ArrayList 客户端 = new ArrayList(); 和 ConcurrentLinkedQueue 客户端 = 新的 ConcurrentLinkedQueue(); 但是你的问题是你试图以线程安全的方式使用有限的资源,所以最好的选择是使用 Semaphore。我已经重新考虑了你的课程以给出一个想法。希望它有所帮助。请仔细查看“SERVER_INSTANCE”。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;

public class Server {
    private final int MAX_AVAILABLE = 4;
    public final Semaphore SERVER_INSTANCE = new Semaphore(MAX_AVAILABLE, true);

    static int port = 4444;
    static volatile boolean listening = true;
    static MatchMaker arena;

    public static void main(String[] args) {
        Initialize();
        Thread startConnections = new Thread(run());
        startConnections.start();
    }

    private static void Initialize() {
        //do somthing
    }

    private static Runnable run(){
        System.out.println("(" +  new SimpleDateFormat("HH:mm:ss").format(new Date()) + ") Started listening on port: " + port);
        ServerSocket socket = null;
        while(listening){
           try {
                socket = new ServerSocket(port);
               try {
                   SERVER_INSTANCE.acquire();
                       Socket clientSocket = socket.accept();
                       MultiThread connection = new MultiThread(clientSocket, arena, SERVER_INSTANCE);

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

        }
        return null;
    }

    static class MultiThread implements Runnable{
        Semaphore serverInstance ;
        public MultiThread(Socket clientSocket, MatchMaker arena, Semaphore serverInstance) {
            serverInstance = serverInstance;
        }

        @Override
        public void run() {
            try {
                serverInstance.acquire();
                //Do your work here
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                serverInstance.release();
            }
        }
    }

        class MatchMaker {

        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2012-04-25
    相关资源
    最近更新 更多