0

我有一个java应用程序,人们可以登录(并用数据库做各种事情,但这不重要)。我可以使用.getInetAddress()获取登录到服务器的人员的IP地址,但是我不确定这些线程之间如何进行通信。我正在尝试为这个预先存在的程序添加聊天服务。如何在java中创建聊天客户端

我的程序使用标准的多线程服务器,而clinet是单线程的AWT Action Listener程序。做这个的最好方式是什么?我的代码包含一个包含main的类,它创建一个新的“Client Handler”类并创建一个新线程来处理它。目前没有线程间通信,线程会在其自己的套接字端口上生成并在服务器上独立运行。我以前的想法包括:

使用ObjectInputStream将客户端置于阻塞状态,并等待客户端接收消息(而不是忙于等待按钮按下),并且条件是客户端要执行一个动作(编辑一个字段),它将释放阻塞I/O并执行该方法,然后返回到程序的阻塞I/O“等待”阶段。

事情我不知道这一点:

  1. 如果我调用阻塞I/O,将AWT的ActionListener疏通阻塞I/O,并跳转到事件处理程序?

  2. 如果客户端在代码中(而不是在阻塞的InputStream上)并且发送消息,服务器是否知道要等到程序返回inputStream之后才发送消息,或者是否会发送消息并创建一个队列,或者更糟糕的是,问题。

  3. 服务器是多线程的,如果John位于192.168.1.100并且Larry位于192.168.1.152并且John想发送消息给Larry,那么我如何从线程处理消息* .100到线程处理* .152,因此它可以输出到正确的客户端在正确的插座上。

我其他的想法(也许更容易之一)将是使客户端多线程,连接到服务器的不同端口上,并使用一套完全不同的套接字连接来处理事件。在这种情况下,我可以使用阻塞I/O等待,当我得到消息时,输出它,然后返回到阻塞I/O。生产代码和聊天代码之间的通信不会有任何问题,并且从这个立场来看它更好,但是这意味着我需要在连接的每个客户端的不同端口上有2个打开的连接。该程序最终会同时连接数千个用户,并且我不想用一个应用程序占用所有服务器端口。

他们的其他方式是不是淹没端口或冒通信错误?

回答

1

你的客户端应该使用3个线程。所有的gui交互应该从EDT完成。然后,您应该有一个用于套接字InputStream的线程和一个用于套接字OutputStream的线程(这两个块都可能会阻塞)。当你想发送消息时,你的gui线程应该使用某种线程安全队列将消息传递给OutputStream线程。 InputStream线程收到的任何消息都应该使用类似SwingUtilities.invokeLater的消息将消息推送到gui。

我不完全确定你在说什么插座和端口。客户端连接到服务器将需要一个单独的套接字连接(这将涉及一个单独的端口)

+0

@jtahlbom不熟悉SwingUtilities.invokeLater,但会看起来,当我有机会。使输入/输出流成为一个独立的类使得我以及线程安全的队列成为可能。尽管我接受了答案,但我希望看到其他人对此有何评论。我说的插槽是,如果我要分开生产代码和聊天服务,并使用两个不同的套接字连接来处理它们(每个套接字一个),我会使套接字要求翻倍。每个Cleint 2个,而不是每个客户1个。 –

+0

@MattWestlake - 对不起,我不明白你的意思是把“生产代码”从“聊天服务”中分离出来。你是通过同一个套接字发送多种类型的数据吗?如果是这样,你是否已经有2个其他线程管理读/写这个“其他”数据? – jtahlborn