3

I've made a simple UDP chat server and client

Client sends a packet containing a string, server receives it.

Upon receipt, the server should be able to tell if the IP AND Port number are in a list of Clients.

I made an object class called ClientDetails,

class ClientDetails {
   int port; 
   String name;
   InetAddress address;

    ClientDetails(InetAddress address, int port, String name) {
        this.address = address;
        this.port = port;
        this.name = name;
    }

and in the Server I create an ArrayList of that object to hold the details of active clients.

I have constructed some If statements and corresponding methods to perform most of the operations, but the crux is finding out whether the user is in the list or not on every packet received.

I want to use something like

if (!IsCurrentlyAUser){
then addNewUserToList();
else checkUserNameValid//ensures the String sent is not one of the keywords(who, whoami, etc)
 addNewUser();}

The idea is that IsCurrentlyAUser checks a method CheckClientExists,

private boolean checkClientExists(InetAddress ip, int port, String name){


    if (!clientList.contains(ip) && !clientList.contains(port)){
    return false;
}
     return true;

    }

Clearly this won't work, but I don't know how to make it or come up with something more viable.

EDIT: To clarify the problem and possibly complicate things:

The check is based on a clients IP AND Port. In that instance, only the ip and port are checked among the records. If they exist, the client continues, if they don't, they get added, wherein the name entered will be checked.

EDIT:

Updated ClientDetails with the following

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + port;
return result;
}





@Override
public boolean equals(Object obj) {
if (this == obj)
    return true;
if (obj == null)
    return false;
if (getClass() != obj.getClass())
    return false;
ClientDetails other = (ClientDetails) obj;
if (address == null) {
    if (other.address != null)
        return false;
} else if (!address.equals(other.address))
    return false;
if (name == null) {
    if (other.name != null)
        return false;
} else if (!name.equals(other.name))
    return false;
if (port != other.port)
    return false;
return true;

}

Running the following in the Main Server

    if(request.equals("who") ||request.equals("whoami")||
        request.equals("all")||request.equals("bye")){
         //do something 
          System.out.println("User Entered Invalid Name ");
         }else{
              System.out.println("User Entered a Valid Name ");
               clientName =request;
              clients.add(new ClientDetails(clientIP,clientPort,clientName));
                    }
             System.out.println("set contains " +clients.toString());

seems to not prevent duplicates, which suggests that the hash/equals is wrong. This was generated by eclipse, which is the best I could do.


You could improve your class ClientDetails, by implementing method hashCode and equals.

Then you will be able to store those data in single Set.

class Clients {

 private final Set<ClientDetails> clients = new HashSet<>();

 public boolean checkClientExists(InetAddress ip, int port, String name){

   return  clients.contains(new ClientDetails(ip,port,name));   

 }

//More code for client management.
}

As your class is simple structure holder you can create a object of it only to check that such element was already created. But note you should try to wrap all those (ip,port,name) in a structure as soon as possible, and use them in your application.

4

1 回答 1

0

ClientDetails您可以通过实现方法hashCode 和 equals来改进您的课程。

然后,您将能够将这些数据存储在单个Set中。

class Clients {

 private final Set<ClientDetails> clients = new HashSet<>();

 public boolean checkClientExists(InetAddress ip, int port, String name){

   return  clients.contains(new ClientDetails(ip,port,name));   

 }

//More code for client management.
}

由于您的类是简单的结构持有者,您可以创建它的一个对象,只是为了检查是否已经创建了这样的元素。但请注意,您应该尽快尝试将所有这些(ip、端口、名称)包装在一个结构中,并在您的应用程序中使用它们。

于 2013-04-04T10:58:42.790 回答