gpt4 book ai didi

java - 并发线程读取套接字

转载 作者:行者123 更新时间:2023-11-29 08:48:23 25 4
gpt4 key购买 nike

我有一个简单的服务器-客户端套接字连接。我将所有数据封装在通过 ObjectStreams 发送的套接字之间来回发送的对象中。

我创建了一个“HeartBeat”监视器,它在一个单独的线程中运行,服务器和客户端每 500 毫秒向后和向前发送一个 HeartBeat(空对象)以检查连接,效果很好。然而,正因为如此,当我想在服务器和客户端之间发送其他数据时,它与这些 HeartBeat 对象混在一起。

例如,我的服务器需要一个登录对象,但却得到了一个 HeartBeat 实例对象。

我的代码是一个简单的客户端/服务器设置,所以我认为没有必要发布他们的代码,但是,HeartBeat 代码如下:

private static final int HEARTBEAT_INTERVAL = 500;

private void addHeartBeatMonitor(final Socket socket) {
this.heartBeatTimer = new Timer();
this.heartBeatTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(new HeartBeat());
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
if (!(is.readObject() instanceof HeartBeat)) { throw new IOException(); }
} catch (IOException e) {
LOG.info("Received disconnect from " + getClientSocket().getInetAddress());
heartBeatTimer.cancel();
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e1) {}
}
} catch (ClassNotFoundException e) {}
}
}, 0, HEARTBEAT_INTERVAL);
}

我的选择似乎如下:

  1. 放弃 HeartBeat 功能,尽管似乎没有其他可靠的方法来检查连接状态。
  2. 找到一些其他类型的 Socket 实现,它会神奇地为我解决所有这些问题。
  3. 有一个同步方法来监督对套接字的所有读取和写入,它会丢弃 HeartBeats 并将其他对象发送到它们应该到达的位置。
  4. 某种同步魔法。

在此先感谢您的帮助!

编辑:读取登录对象的代码(服务器端):

User result = null;
try {
ObjectInputStream is = new ObjectInputStream(this.getInputStream());
Login request = (Login) is.readObject(); ### ERROR ###
result = this.mongoService.login(request);
ObjectOutputStream os = new ObjectOutputStream(this.getOutputStream());
os.writeObject(result);
} catch (IOException e) {
} catch (ClassNotFoundException e) {}
return result;

异常如下:

Exception in thread "Thread-0" java.lang.ClassCastException: model.HeartBeat cannot be cast to model.Login
at socket.SocketServerWorker.login(SocketServerWorker.java:78)
at socket.SocketServerWorker.<init>(SocketServerWorker.java:47)
at socket.SocketServer$2.run(SocketServer.java:50)
at java.lang.Thread.run(Thread.java:744)

最佳答案

考虑做这样的事情。我只是把它放在一起,所以它显然未经测试,但我相信你会明白的:

public class HeartBeatMonitor
{
final Map<Class,Consumer> handlers = new HashMap<> ();
final Socket sock;
final ObjectInputStream is;
final ObjectOutputStream os;

public HeartBeatMonitor (final Socket sock)
{
try
{
this.sock = sock;
this.is = new ObjectInputStream (sock.getInputStream ());
this.os = new ObjectOutputStream (sock.getOutputStream ());
}
catch (final IOException e)
{
throw new RuntimeException (e);
}
}

public <T> void setHandler (final Class<T> type, final Consumer<? super T> handler)
{
this.handlers.put (type, handler);
}

// This would be called in a loop
void accept () throws ClassNotFoundException, IOException
{
final Object o = this.is.readObject ();
final Consumer handler = this.handlers.get (o.getClass ());
if (handler != null)
handler.accept (o);
// Else default handler?
}
}

关于java - 并发线程读取套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23965202/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com