skiwi
skiwi

Reputation: 69379

Java questions regarding client server model

I have several questions regarding a client server model. My current application (or rather my proposed one) uses a central server and different clients can connect to it.

(Small explanation of O(n) for people wanting to answer the questions and not knowing about it, either google or follow this example:

Consider a list with n elements. O(1) means that you can just pick the element and O(n) basically means that you possibly have to iterate over every element (thus n elements) to get the item you want. And O(log n) is a middle way having to do with recursive subdivision which is still a lot faster as O(n) but not as fast as O(1).)

Question 1:

How can I efficiently retrieve records of users, I got no clue how many users the server will have to handle at some point, but I strongly believe that O(n) operations just will not suffice if O(1) is reasonble to implement.

First part is about the login procedure, I plan to let the user login with a personal identifier (username/email/etc.) and a password, this information gets sent to the server once someone tries to log in.

Furthermore I also plan to not use a database (for example MySQL) directly, but purely for 'backup' purposes (the server should store all information in RAM if possible, and only write it to the database such that nothing gets lost when power gets lost).

So basically the server needs to store the Client data (including the personal identifier, but also an unique ID).

My current ideas:

  1. Store in a List, however then searching for a user (and then validate his information) may take O(n) time depending on the sorting, I could cut it down to O(log n) if I do something with alphabetical sorting on username.

  2. Second proposal would be to store it in a Client[] array with the UniqueID's as keys. Then access in O(1) should be possible which is ideal, however the problem I am having with that approach is how do I convert the personal identifier (username, etc.) which the user puts in and sends to the server, to his unique ID? If I use anything like a List then the time will be O(n) again. Moreover, the array size may not be unproportionally huge, as it would simply allocate too much memory, for example I do not think that hashing the users name is ideal nor am I sure if it creates a unique ID.

Question 2:

Secondly I also want my userdata to be secure of course. Now assume that the underlying MySQL server (from which the data gets loaded into server's RAM at startup) is secure.

Then I wonder are the saved passwords (encrypted of course) also safe given these conditions?

  1. Nothing has direct physical access to the server.

  2. The communication protocol has no commands to retrieve password information or a superset including the password information, meaning that the server will under no conditions give out the password.

  3. The passwords are stored as private variables in the Client objects that hang around in the server's RAM.

  4. To check if the information a user has entered, is correct the Client object has a function like client.confirmPassword(password).

So unless I have forgotten things, the question basically comes down to can the RAM of the Server be directly read given that it is only connected to the outside world via a communication protocol?

Post turned out to be pretty long, but I hope there are people around that can answer these questions :)

Upvotes: 0

Views: 165

Answers (4)

DeltaLima
DeltaLima

Reputation: 5944

Contrary to the answer tkr's answer, Hashmap has not O(1) performance. Please see this question: "Is a java hasmap really O(1)"

Depending on the multithreaded nature of your server and the way you would like to do synchronization, you could still use a Hashmap or Hashtable, but bear in mind that the performance is somewhere between O(1) and O(n), depending on the number of hash collisions. Also keep in mind that the hash function itself will cause overhead. Alternatively you might want to look into a binary tree (O(log(n))

My choice would still be to use a database; as others have said, databases store data that is frequently accessed into memory, and therefore are well suited for this kind of tasks. You could run a local in-memory database (e.g. HSQLDB) and flush the data to an external server upon shutdown, and load it from there upon startup.

As for storing passwords in a database, make sure that you use a secure hash function such as SHA-1. Don't forget to salt the password in order to make decryption of password even harder if someone would get access to your password database accidentally.

Upvotes: 1

Chris Hughes
Chris Hughes

Reputation: 342

  1. The easy answer is just to use a database, because someone else has already spent the time to make it fast and optimized for you. You can check out mysql features like caching and in-memory tables which will help with performance. But if you really don't want to use a database, then you should hash the usernames. Provided your usernames are unique, which they would have to be, then a good hash will always provide a unique id. You could also look into things like TreeMaps if you're interested in exploring other options.
  2. It really depends on what you're most concerned about. A good hacker can do all sorts of surprising things you wouldn't have expected. Your best defense is making sure that anything running on the server that you don't need is uninstalled, and any ports you aren't using are closed.

Upvotes: 1

tkr
tkr

Reputation: 1381

Question 1)

I would consider the use of a hashmap. It has has access in O(1). You could even use multiple hashmaps:

  • Map userById
  • Map userByName

You should have a look at different map implementations because of concurreny.

Question 2)

As long as the password is properly encrypted I think you are fine. In regular circumstances the server Memory is considered safe.

Probably this other question is of interest for you: Best way to store password in database

Upvotes: 1

DarthCoder
DarthCoder

Reputation: 354

You are worrying about wrong reasons

  1. There is one thing that you need to understand is that database system is a complex system. The search query is very complex and the performance is very high and you needn't be afraid to use it where ever required. Database systems actually get all the information of the active databases to memory ... and they are cached and then only written to hard-drive once the service is closed : this is what you are trying to redo.
  2. MD5 and SHA1 are powerful hashes that can be stored instead of passwords directly. you can find calls to these in most of the programing languages. Now you can store these hash in the database and then do a compare on the hash, which is extremely secure.

it is a lot easier to do things for which solutions are already built like databases, libraries etc. They are made for performance and are very immune to wrong inputs also have better ways to deal with worst case scenarios.

Upvotes: 1

Related Questions