2013-05-02 68 views
2

我一直在思考这一整天,我真的不认为如果标题是正确的,但在这里,让我解释一下我的情况:我正在一个项目中使用Java编写的服务器,用于在Delphi中创建客户端。连接线很好,多个客户端有自己的线程,I/O工作良好。客户端发送字符串到我用BufferedReader读取的服务器。根据服务器收到的保留字,它会执行一个操作。在客户端发送字符串之前,它会将信息插入SQL Server数据库,以便服务器可以在通过套接字获取订单/命令后进行检查。服务器获取数据库中的信息,处理它,然后发送给...我们称之为“黑暗的一面”。如何获取没有引用变量的套接字对象?

当交易完成,信息发送到黑暗的一面时,服务器会插入信息......咳嗽咳嗽,黑暗的信息到数据库表中,以便客户端可以去接受请求。但是,我需要向客户报告这一点! (“哟,再次检查数据库兄弟,你想要的是:3”)。

连接,插座是在其他类中。不是我想用来回答客户端的那个,所以如果我没有套接字,我没有OutputStream,我需要回应。那个班,处理和发送信息到黑暗的那个班,将会与成百上千的小组成员一起工作。

我的问题是在这里:我不能向客户报告已完成,因为我没有该类中的套接字引用。我实例的客户线程,如:

new Client(socket).start(); 

对象,而不引用变量,但是,我有一个选项,我可以采取:目前存放在一个HashMap对象的插座和自己的IP的一个新的连接时,像这样的:

sockets.put(newSocket.getInetAddress().getHostAddress(), newSocket); 

然后我就可以拿到插座(这样我就可以得到的OutputStream和答案)调用这样一个静态方法:

public static Socket getSocket(String IP) { 

     Socket RequestedSocket; 
     RequestedSocket = sockets.get(IP); 

     return RequestedSocket; 
    } 

但我想,如果你告诉我有是一个更好的方式,比将所有这些套接字存储在列表/散列表中更好。我怎样才能得到这些没有引用变量的对象?或者也许这是一个很好的做法,我只是想超越极限。

P.S .:我尝试将客户端对象存储在数据库中,将它们序列化,但套接字无法序列化。

谢谢。

+0

是什么使人从'Client'类保持一个参考? – A4L 2013-05-02 18:51:19

+0

客户端类(新客户端())中有一个引用,但我没有为客户端类提供所有引用。感谢您回复 – user2245180 2013-05-02 19:00:33

+1

我建议您以某种方式跟踪客户,而不是套接字,然后向Client类中添加一个方法来通知客户端,例如Client#notify(“data is available”)。 ' – A4L 2013-05-02 19:08:35

回答

0

这是您的设计问题。你需要在某个地方跟踪它们,一种解决方案可能是简单地创建一个单例类[SocketMapManager]作为包含hashmap的实例,以便你可以从其他类静态访问它。 http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html

+0

的消息如果这些套接字连接时间不确定,会不会想到这些套接字连接?你认为单身人士是一个拥有连接或者共享池的地方吗?你有这方面的经验吗(套接字和开放的流)? – tgkprog 2013-05-03 09:52:31

0

任何告诉你保持对套接字/连接/流的引用的解决方案都不好 - >因为这意味着你的连接将在服务器完成工作时被阻止。

你有几个选择打开 1.有客户也作为服务器。当他们连接时,他们将服务器的IP,端口和一些秘密字符串作为握手的一部分。这意味着您可以控制客户端代码以实现此目的。

  1. 服务器有一个协议,可以接收新作业或检查旧作业的状态。客户端会定期池化服务器。

  2. 客户端连接到数据库,或者连接到数据库得到这份工作的状态其它应用(Web服务或普通插座像原来的应用程序)。含义服务器给客户一个工作ID。

一个套接字打开,然后它打开一个操作系统资源。可以读取Network Programming: to maintain sockets or not?

全部取决于 1.多少客户端连接在一个时间/在5分钟内。 2.一个客户的请求需要多少秒/分钟的处理

如果客户在5分钟内的客户数量最多(在未来3年)300每次/在任何5分钟的持续时间,每个请求需要在最多50秒处理,然后专用服务器最多50,000个插槽应该就足够了。否则,你需要异步或多个服务器(和DNS/Web服务器/端口的负载均衡转发或其他方式)

+0

感谢您的回答。我喜欢这样做,这将是非常好的,客户自己做事,如果事务已完成,存储ID或IP,就会发出警告。但是,我忘了说我没有任何控制客户端代码。 – user2245180 2013-05-02 20:45:22

+0

为什么保持一个引用会阻塞连接?请解释。 – EJP 2013-05-02 21:41:22

+0

编辑答案。不知道为什么倒票? – tgkprog 2013-05-03 08:25:32

0

我有一点想明白什么是操作流程,以及什么问题正是你在处置。这个序列是否正确?
1.客户端写入数据库(DELPHI)
2.客户端写入服务器(DELPHI)
3.服务器写入数据库(JAVA)
4.服务器写入客户机(JAVA)
5.客户端读取数据库(德尔福)
而问题是通过4?

更重要的是:您是说Client班中没有插座,并且您也没有Client的列表?
您是否可以使用反射来搜索/获取Client的套接字引用?
如果你说你没有套接字,你怎么可以在HashMap中添加这个套接字?
最后但并非最不重要的是:为什么你需要存储套接字?也许每个客户端都打开一个用于多个请求的连接?

这可能是美的,如果所有的答案可以传达到只有一个IP:端口...

+0

序列正确。我说“我没有插口”,但我的意思是在课堂上将被用来回答。因为我安装了每个没有标识符的线程,所以套接字是无法访问的,至少我创建了一个HashMap或者它们的列表。我可以得到客户端的IP和端口,但据我所知:客户端套接字的IP和端口不足以从Java发送/接收数据,我希望我错了。 – user2245180 2013-05-06 13:15:32

+0

但是,如果你用'socket'初始化'Client',你不能使用例如一个带有'socket'和'Client'的结构链表吗?这样你就可以拥有他们两个。你甚至可以通过套接字的'hashCode()'来保持它的顺序,所以它的速度更快...... 如果你必须用套接字手动回答客户端,Client类正在做什么? – lunadir 2013-05-06 14:24:08

相关问题