限制将通过服务器连接的客户端数量

时间:2019-05-04 18:08:14

标签: java multithreading server client chatroom

我需要限制可以连接到服务器的客户端数量。我只想要3个客户端,它们不能连接更多。

我尝试了其他条件。和一些循环。

public class server {

    ServerSocket ss;
    boolean quite=false;
    ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();

    public static void main(String[] args) {
        new server();

    }
    public server() {
        try {
            //TODO use method to take this as an input from user)
            ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
            while(!quite)
            {
                Socket s=ss.accept();//when a connection to the domain is found we accept it
                MultiServerConnection OurConnection = new MultiServerConnection(s,this);
                OurConnection.start();//Start Thread
                OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//make sure its bloody same with client it took my 15 min to realize that XD
    }
}

public class MultiServerConnection extends Thread {

    Socket s;
    DataInputStream din;
    DataOutputStream dout;
    server ss;
    boolean quite=false;

    public MultiServerConnection(Socket OurSocket,server OurServer)
    {
        super("MultiServerConnection");//server connection thread
        this.s=OurSocket;
        this.ss=OurServer;
    }

    public void ServerOutClientIn(String OutText)
    {
        try {
            long ThreadID=this.getId();
            dout.writeUTF(OutText);
            dout.flush();//this is because of a buffer error :<
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void ServerOutAllClientIn(String OutText)
    {
        for(int i=0;i<ss.OurDomainsConnections.size();i++)
        {
            MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
            Connection.ServerOutClientIn(OutText);
        }
    }

    public void run()
    {
        try {
            din=new DataInputStream(s.getInputStream());
            dout=new DataOutputStream(s.getOutputStream());

            while(!quite)
            {
                while(din.available()==0)
                {
                    try {
                        Thread.sleep(1);//sleep if there is not data coming
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                String ComingText=din.readUTF();
                ServerOutAllClientIn(ComingText);
            }
            din.close();
            dout.close();
            s.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

public class MultiClients extends Thread {

    Socket s;
    DataInputStream din;
    DataOutputStream dout;
    boolean quite=false;
    public ClientData c;
    public interface1 GUI;

    public MultiClients(Socket OurMultiSocket, interface1 gui)
    {
        s=OurMultiSocket;
        c=new ClientData();
        GUI=gui;
    }
    public void ClientOutServerIn(String Text)
    {
        //write the line from console to server
        try {
            if(Text.equals("change channel"))
            {
                System.out.print("sending changing channel: "+Text+"\n");
                dout.writeUTF(Text);
                dout.flush();
            }
            else if(Text.equals("new user"))
            {
                System.out.print("sending new user: "+ Text+"\n");
                dout.writeUTF(Text+":"+c.GetName()+"="+c.GetChannel());
                dout.flush();
            }
            else
            {
                dout.writeUTF(c.GetChannel()+"="+this.getName()+": "+Text);
                dout.flush();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }
    public void SetClient(String channel,String Name)
    {
        c.SetName(Name);
        c.SetChannel(channel);
    }
    public void run()
    {
        try {
            din=new DataInputStream(s.getInputStream());
            dout=new DataOutputStream(s.getOutputStream());
            while(!quite)
            {
                try {
                    while(din.available()==0)
                    {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    //if there is something just show it on console
                    //and then go back and do the same
                    String reply=din.readUTF();
                    String Chan=ExtractChannel(reply);
                    String name=ExtractName(reply);
                    /*if (reply.equals("change channel"))
                    {
                        System.out.print("changing channel in body: "+reply+"\n");
                        //GUI.ClearDisplay();
                        setChangedChannel();
                    }*/
                    if(name.equals("new user"))
                    {
                        System.out.print("new user in body: "+reply+"\n");
                        //GUI.ClearDisplay();
                        setChannel(reply);
                    }
                    else
                    {
                        PrintReply(Chan,reply);
                    }
                    //System.out.println(reply);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    try {
                        din.close();
                        dout.close();
                        s.close();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }   
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            try {
                din.close();
                dout.close();
                s.close();
            } catch (IOException x) {
                // TODO Auto-generated catch block
                x.printStackTrace();
            }
        }
    }
    public void CloseClient()
    {
        try {
            din.close();
            dout.close();
            s.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public String ExtractName(String x)
    {
        String[]Y=x.split(":");
        return Y[0];
    }
    public String ExtractChannel(String X)
    {
        String[]Y=X.split("=");
        return Y[0];
    }
    public void PrintReply(String Chan,String Rep)
    {
        if(c.GetChannel().equals(Chan))
        {
            String []Y=Rep.split("=");
            GUI.setDisplay(Y[1]);
            //System.out.println(Y[1]+"\n \n \n \n");
        }

    }
    public void setChannel(String x)
    {
        String []Y=x.split(":");
        String []Z=Y[1].split("=");
        System.out.print("setting "+Z[0]+" channel to "+Z[1]+"\n");
        GUI.setUserInChannel(Z[0]);
    }
    public void setChangedChannel()
    {
        GUI.setUserInChannel(c.GetName()+": "+c.GetChannel());
    }
    class ClientData
    {
        public String ClientName;
        public String channel;

        public void SetChannel(String Chan)
        {
            channel=Chan;
        }
        public void SetName(String name)
        {
            ClientName=name;
        }
        public String GetChannel()
        {
            return channel;
        }
        public String GetName()
        {
            return ClientName;
        }
    }

}

在此代码中。超过5位用户可以一起聊天。我只想允许3个用户连接并聊天。

1 个答案:

答案 0 :(得分:1)

您可以使用AtomicInteger作为计数器来检查您已经连接了多少个客户端:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

public class server {

    ServerSocket ss;
    boolean quite=false;
    ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
    final AtomicInteger runningCount = new AtomicInteger(0);
    final Integer limit = 3;

    public static void main(String[] args) {
        new server();

    }
    public server() {
        try {
            //TODO use method to take this as an input from user)
            ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
            while(!quite)
            {

                Socket s=ss.accept();//when a connection to the domain is found we accept it
                if (runningCount.incrementAndGet() < limit){ //increment number of clients and check
                    MultiServerConnection OurConnection = new MultiServerConnection(s,this, runningCount::decrementAndGet);
                    OurConnection.start();//Start Thread
                    OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
                } else {
                    runningCount.decrementAndGet();
                    s.close();
                    System.out.println("limit exceeded");
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }//make sure its bloody same with client it took my 15 min to realize that XD
    }
}

interface Callback {
   void call();
}

class MultiServerConnection extends Thread {

    Socket s;
    DataInputStream din;
    DataOutputStream dout;
    server ss;
    boolean quite=false;
    final Callback callbackOnFinish;

    public MultiServerConnection(Socket OurSocket,server OurServer, Callback callbackOnFinish)
    {
        super("MultiServerConnection");//server connection thread
        this.s=OurSocket;
        this.ss=OurServer;
        this.callbackOnFinish = callbackOnFinish;
    }

    public void ServerOutClientIn(String OutText)
    {
        try {
            long ThreadID=this.getId();
            dout.writeUTF(OutText);
            dout.flush();//this is because of a buffer error :<
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void ServerOutAllClientIn(String OutText)
    {
        for(int i=0;i<ss.OurDomainsConnections.size();i++)
        {
            MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
            Connection.ServerOutClientIn(OutText);
        }
    }

    public void run()
    {
        try {
            din=new DataInputStream(s.getInputStream());
            dout=new DataOutputStream(s.getOutputStream());

            while(!quite)
            {
                while(din.available()==0)
                {
                    try {
                        Thread.sleep(1);//sleep if there is not data coming
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                String ComingText=din.readUTF();
                ServerOutAllClientIn(ComingText);
            }
            din.close();
            dout.close();
            s.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            callbackOnFinish.call();
        }
    }
}

当接受新连接时,runningCount会自动增加,并且值将由runningCount.incrementAndGet()获得。然后,如果值低于限制-使用回调创建新的MultiServerConnection。回调用于在退出时递减计数器。如果计数器等于或大于限制=>套接字将关闭,并显示错误消息。最好将消息传递到套接字。

P.S。我尚未审查您的解决方案。我刚刚添加了您要求的功能。