关于客户端服务器模型的Java问题

时间:2013-05-03 16:48:33

标签: java client-server

我有几个关于客户端服务器模型的问题。 我当前的应用程序(或者更确切地说是我提出的应用程序)使用中央服务器,不同的客户端可以连接到它。

(O(n)的小解释对于想要回答问题而不知道它的人来说,谷歌或遵循这个例子:

考虑一个包含n个元素的列表。 O(1)意味着你可以只选择元素而O(n)基本上意味着你可能必须迭代每个元素(因此n个元素)来获得你想要的项目。 O(log n)是一种与递归细分有关的中间方法,它仍然比O(n)快得多,但不如O(1)快。)

问题1:

如何有效地检索用户记录,我不知道服务器在某些时候必须处理多少用户,但我坚信如果O(1)是合理的,O(n)操作是不够的实施。

第一部分是关于登录程序,我打算让用户使用个人标识符(用户名/电子邮件等)和密码登录,一旦有人试图登录,这些信息就会被发送到服务器。

此外,我还计划不直接使用数据库(例如MySQL),但纯粹用于“备份”目的(如果可能,服务器应将所有信息存储在RAM中,并且只将其写入数据库,以免丢失任何内容)当电力丢失时。)

基本上服务器需要存储客户端数据(包括个人标识符,还有唯一ID)。

我目前的想法:

  1. 存储在列表中,然后搜索用户(然后验证他的信息)可能需要O(n)时间,具体取决于排序,如果我这样做,我可以将其减少到O(log n)用户名按字母排序的东西。

  2. 第二个提议是将其存储在ClientID数组中,并将UniqueID作为键。然后在O(1)中访问应该是可能的,这是理想的,但是我使用该方法的问题是如何将用户放入并发送到服务器的个人标识符(用户名等)转换为他的唯一身份?如果我使用像List这样的东西,那么时间将再次为O(n)。此外,数组大小可能不会非常大,因为它只会分配太多内存,例如我不认为散列用户名是理想的,也不确定它是否创建了唯一的ID。

  3. 问题2:

    其次我还希望我的userdata当然是安全的。现在假设底层MySQL服务器(数据在启动时从中加载到服务器的RAM中)是安全的。

    那么我想知道在这些条件下保存的密码(当然是加密的)也是安全的吗?

    1. 没有任何东西可以直接物理访问服务器。

    2. 通信协议没有检索密码信息的命令或包含密码信息的超集,这意味着服务器在任何情况下都不会给出密码。

    3. 密码作为私有变量存储在服务器RAM中的客户端对象中。

    4. 要检查用户输入的信息是否正确,客户端对象的功能如client.confirmPassword(password)

    5. 因此,除非我忘记了事情,否则问题基本上归结为服务器的RAM可以直接读取,因为它只通过通信协议连接到外部世界吗?

      帖子结果很长,但我希望周围有人可以回答这些问题:)

4 个答案:

答案 0 :(得分:1)

你担心错误的原因

  1. 您需要了解的一件事是数据库系统是一个复杂的系统。搜索查询非常复杂,性能非常高,您无需担心在需要的地方使用它。数据库系统实际上将活动数据库的所有信息都存储到内存中...并且它们被缓存,然后只有在服务关闭时才写入硬盘驱动器:这就是您要重做的内容。
  2. MD5和SHA1是强大的哈希值,可以直接存储而不是密码。你可以在大多数编程语言中找到这些调用。现在,您可以将这些哈希存储在数据库中,然后对哈希进行比较,这非常安全。
  3. 对于已经构建了数据库,库等解决方案的事情要容易得多。它们是针对性能而设计的,并且对错误的输入非常不敏感,也有更好的方法来处理最坏的情况。

答案 1 :(得分:1)

问题1)

我会考虑使用hashmap。它可以访问O(1)。 您甚至可以使用多个哈希图:

  • 映射userById
  • 映射userByName

你应该看看不同的地图实现,因为concurreny。

问题2)

只要密码已正确加密,我认为您没事。在常规情况下,服务器内存被认为是安全的。

您可能会感兴趣的另一个问题是: Best way to store password in database

答案 2 :(得分:1)

  1. 简单的答案就是使用数据库,因为其他人已经花了很多时间让它快速并为您优化。您可以查看mysql功能,如缓存和内存表,这将有助于提高性能。但是如果你真的不想使用数据库,那么你应该对用户名进行哈希处理。如果您的用户名是唯一的,他们必须是,那么好的哈希将始终提供唯一的ID。如果您有兴趣探索其他选项,也可以查看TreeMaps之类的内容。
  2. 这真的取决于你最关心的是什么。一个好的黑客可以做各种你不会想到的令人惊讶的事情。您最好的防御是确保卸载在您不需要的服务器上运行的任何东西,并且关闭您未使用的任何端口。

答案 3 :(得分:1)

与答案tkr的答案相反,Hashmap没有O(1)性能。请看这个问题:"Is a java hasmap really O(1)"

根据服务器的多线程特性以及您希望进行同步的方式,您仍然可以使用HashmapHashtable,但请记住,性能介于O之间( 1)和O(n),取决于散列冲突的数量。还要记住,哈希函数本身会导致开销。 或者,您可能希望查看二叉树(O(log(n))

我的选择仍然是使用数据库;正如其他人所说,数据库存储经常被访问到内存中的数据,因此非常适合这种任务。您可以运行本地内存数据库(例如HSQLDB)并在关闭时将数据刷新到外部服务器,并在启动时从那里加载它。

至于在数据库中存储密码,请确保使用安全散列函数,例如SHA-1。如果有人无意中访问您的密码数据库,请不要忘记salt密码,以便更难解密密码。